JavaScript探秘:JScript的内存管理

命名函数表达式会导致产生多余的函数对象
服务器君一共花费了216.065 ms进行了5次数据库查询<,努力地为您提供了这个页面>。
试试阅读模式<?希望听取您的建议

知道了这些不符合规范的代码解析bug以后<,我们如果用它的话,就会发现内存方面其实是有问题的>,来看一个例子:

  var f = (function(){
    if (true) {
      return function g(){};
    }
    return function g(){};
  })();

我们知道,这个匿名函数调用返回的函数(带有标识符g的函数)>,然后赋值给了外部的f。我们也知道,命名函数表达式会导致产生多余的函数对象<<,而该对象与返回的函数对象不是一回事>>。所以这个多余的g函数就死在了返回函数的闭包中了,因此内存问题就出现了<。这是因为if语句内部的函数与g是在同一个作用域中被声明的<<。这种情况下 ><,除非我们显式断开对g函数的引用>,否则它一直占着内存不放。

  var f = (function(){
    var f, g;
    if (true) {
      f = function g(){};
    }
    else {
      f = function g(){};
    }
    // 设置g为null以后它就不会再占内存了
    g = null;
    return f;
  })();

通过设置g为null><,垃圾回收器就把g引用的那个隐式函数给回收掉了>,为了验证我们的代码,我们来做一些测试,以确保我们的内存被回收了。

测试

测试很简单>,就是命名函数表达式创建10000个函数>,然后把它们保存在一个数组中。等一会儿以后再看这些函数到底占用了多少内存<。然后>,再断开这些引用并重复这一过程。下面是测试代码:

  function createFn(){
    return (function(){
      var f;
      if (true) {
        f = function F(){
          return 'standard';
        };
      }
      else if (false) {
        f = function F(){
          return 'alternative';
        };
      }
      else {
        f = function F(){
          return 'fallback';
        };
      }
      // var F = null;
      return f;
    })();
  }

  var arr = [ ];
  for (var i=0; i < 10000; i++) {
    arr[i] = createFn();
  }

通过运行在Windows XP SP2中的任务管理器可以看到如下结果:

  IE6:

    without `null`:   7.6K -> 20.3K
    with `null`:      7.6K -> 18K

  IE7:

    without `null`:   14K -> 29.7K
    with `null`:      14K -> 27K

如我们所料<,显示断开引用可以释放内存,但是释放的内存不是很多<,10000个函数对象才释放大约3M的内存<,这对一些小型脚本不算什么,但对于大型程序>,或者长时间运行在低内存的设备里的时候,这是非常有必要的。

关于在Safari 2.x中JS的解析也有一些bug>,但介于版本比较低>>,所以我们在这里就不介绍了>,大家如果想看的话<,请仔细查看英文资料>>。

延伸阅读

此文章所在专题列表如下:

  1. 我们应该如何去了解JavaScript引擎的工作原理
  2. JavaScript探秘:编写可维护的代码的重要性
  3. JavaScript探秘:谨慎使用全局变量
  4. JavaScript探秘:var预解析与副作用
  5. JavaScript探秘:for循环(for Loops)
  6. JavaScript探秘:for-in循环(for-in Loops)
  7. JavaScript探秘:Prototypes强大过头了
  8. JavaScript探秘:eval()是“魔鬼”
  9. JavaScript探秘:用parseInt()进行数值转换
  10. JavaScript探秘:基本编码规范
  11. JavaScript探秘:函数声明与函数表达式
  12. JavaScript探秘:命名函数表达式
  13. JavaScript探秘:调试器中的函数名
  14. JavaScript探秘:JScript的Bug
  15. JavaScript探秘:JScript的内存管理
  16. JavaScript探秘:SpiderMonkey的怪癖
  17. JavaScript探秘:命名函数表达式替代方案
  18. JavaScript探秘:对象Object
  19. JavaScript探秘:原型链 Prototype chain
  20. JavaScript探秘:构造函数 Constructor
  21. JavaScript探秘:可执行的上下文堆栈
  22. 执行上下文其一:变量对象与活动对象
  23. 执行上下文其二:作用域链 Scope Chains
  24. 执行上下文其三:闭包 Closures
  25. 执行上下文其四:This指针
  26. JavaScript探秘:强大的原型和原型链
  27. JavaScript函数其一:函数声明
  28. JavaScript函数其二:函数表达式
  29. JavaScript函数其三:分组中的函数表达式
  30. JavaScript函数其四:函数构造器
  31. JavaScript变量对象其一:VO的声明
  32. JavaScript变量对象其二:VO在不同的执行上下文中
  33. JavaScript变量对象其三:执行上下文的两个阶段
  34. JavaScript变量对象其四:关于变量
  35. JavaScript变量对象其五:__parent__ 属性
  36. JavaScript作用域链其一:作用域链定义
  37. JavaScript作用域链其二:函数的生命周期
  38. JavaScript作用域链其三:作用域链特征
  39. JavaScript闭包其一:闭包概论
  40. JavaScript闭包其二:闭包的实现
  41. JavaScript闭包其三:闭包的用法

本文地址:http://www.jzjxzzjx.com/librarys/veda/detail/1637>>,欢迎访问原出处。

不打个分吗<?

转载随意<,但请带上本文地址:

http://www.jzjxzzjx.com/librarys/veda/detail/1637

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D<>,或点此 加入收藏>>。

阅读一百本计算机著作吧>,少年

很多人觉得自己技术进步很慢<,学习效率低>>,我觉得一个重要原因是看的书少了。多少是多呢>?起码得看3、4><、5、6米吧。给个具体的数量<,那就100本书吧<>。很多人知识结构不好而且不系统<,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题>。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话<,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官<<,但是在知识结构体系以及心理上我们就居高临下>。

所以<,阅读一百本计算机著作吧<,少年<!

《编程之美:微软技术面试心得》 《编程之美》小组 (作者)

《编程之美:微软技术面试心得》是一本让人着迷的书!阅读起来。有些题目的内容会引起强烈的共鸣,尤其是那些自己非常熟悉并且又深知解答的题目;也有一些题目让我异常惊诧,原来除了我所知道的解答思路之外<,还有更好的解答以及更深层次的原因?<;褂幸恍┨饽渴谴永疵幌氲焦?>>。阅读过程是一次愉快的享受,也是脑细胞持续活跃的过程。

更多计算机宝库...

ASP300源码下载 | 微信红包群 | 设计 | 厦门旅游景点 | 旅游中国新闻网 | 钛媒体 | 健康网hsdcba | 每天资讯 | 广西农业技术信息 | 农业种植技术 |