关于JavaScript内存泄漏的质疑
2015-03-03 11:51
260 查看
近几天看了些关于JavaScript内存管理的文章,相对于Java JVM的内存管理,显得简单些。
在学习的过程中,发现有不少网友谈到了循环引用,说循环引用会造成内存泄漏,垃圾回收器无法回收。
实际上,并没有这么可怕,根据小菜目前的了解,这种循环引用造成的内存泄漏,仅仅会发生在低版本的IE浏览器上,现代浏览器是不会这么蠢的。
举个例子,网络上流行的说法大致有如下两种:
一个简单的页面,上边两个按钮,分别调用两个会造成内存泄漏的方法。
借助于Chrome浏览器的Profiles功能,生成内存快照,然后对比,发现这两种写法在谷歌浏览器下均没有泄漏问题。
具体做法是:
打开页面不做任何操作,直接生成页面内存快照。
点击按钮,然后再次生成内存快照。
对比两次内存变化。
不断重复这个过程,生成7、8个快照,趋于稳定,会发现往后内存根本没有变化。
每次生成快照之前,都会强制执行GC(垃圾回收),说明我们每次构造的循环引用,马上被回收了,所以不会出现在快照中。
接下来从理论角度说说为什么应该被回收。
因为这些循环引用,说白了都是无效引用。可以简单理解为:只有从栈区发起的引用才是有效的。本例中的引用,是堆区对象的互相引用,虽然引用计数不为0,但是不可到达,在回收内存时直接就被消灭了。
再深入了说,低版本IE浏览器采用的是引用计数机制回收内存,互相引用造成对方计数互不为0,导致无法回收。
而现代浏览器,采用的是Cheney算法,大致就是把内存分为两份,不断的来回复制,这样那些不可到达的对象,就无法复制,自然被回收了。
栈区、静态、常量之类的字眼,一般是代表root(根)区,只有从这些地方发出的引用,才是可到达的,有效的。
在学习的过程中,发现有不少网友谈到了循环引用,说循环引用会造成内存泄漏,垃圾回收器无法回收。
实际上,并没有这么可怕,根据小菜目前的了解,这种循环引用造成的内存泄漏,仅仅会发生在低版本的IE浏览器上,现代浏览器是不会这么蠢的。
举个例子,网络上流行的说法大致有如下两种:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=640, initial-scale=0.5, user-scalable=no" /> <title>循环引用内存分析</title> <style> </style> </head> <body> <input type="button" onclick="Problem();" value="call Problem"> <input type="button" onclick="MyBindEvent();" value="call MyBindEvent"> </body> <script> //闭包引起的隐式循环引用 function MyBindEvent(){ var obj=document.createElement("div"); obj.onclick=function(){ //Even if it's a empty function }; } //显式循环引用 function Problem() { var objA = new Object(); var objB = new Object(); objA.someOtherObject = objB; objB.anotherObject = objA; } </script> </html>
一个简单的页面,上边两个按钮,分别调用两个会造成内存泄漏的方法。
借助于Chrome浏览器的Profiles功能,生成内存快照,然后对比,发现这两种写法在谷歌浏览器下均没有泄漏问题。
具体做法是:
打开页面不做任何操作,直接生成页面内存快照。
点击按钮,然后再次生成内存快照。
对比两次内存变化。
不断重复这个过程,生成7、8个快照,趋于稳定,会发现往后内存根本没有变化。
每次生成快照之前,都会强制执行GC(垃圾回收),说明我们每次构造的循环引用,马上被回收了,所以不会出现在快照中。
接下来从理论角度说说为什么应该被回收。
因为这些循环引用,说白了都是无效引用。可以简单理解为:只有从栈区发起的引用才是有效的。本例中的引用,是堆区对象的互相引用,虽然引用计数不为0,但是不可到达,在回收内存时直接就被消灭了。
再深入了说,低版本IE浏览器采用的是引用计数机制回收内存,互相引用造成对方计数互不为0,导致无法回收。
而现代浏览器,采用的是Cheney算法,大致就是把内存分为两份,不断的来回复制,这样那些不可到达的对象,就无法复制,自然被回收了。
栈区、静态、常量之类的字眼,一般是代表root(根)区,只有从这些地方发出的引用,才是可到达的,有效的。
相关文章推荐
- 关于Javascript的内存泄漏问题
- 关于ie的内存泄漏与javascript内存释放
- 关于ie的内存泄漏与javascript内存释放
- 关于Javascript的内存泄漏问题的整理稿
- 关于Javascript的内存泄漏问题的整理稿
- 关于ie的内存泄漏与javascript内存释放
- 关于Javascript的内存泄漏问题的整理稿
- 关于ie的内存泄漏与javascript内存释放
- 关于IE的内存泄漏与JavaScript内存释放
- 关于使用javascript改变诸如ListBox控件的各个Item的值及顺序后怎么获取改变后的顺序
- 关于javascript的两个重要的应用
- javascript写的关于静态页面获取URL传递参数的函数[原创]
- 关于WEB交互式设计,JavaScript以及AJAX的一点心得
- 关于javascript中parseInt函数的一个所谓的bug
- 关于vbscript 与 javascript如何传递变量(包括服务器端与客户端)
- 关于在vs2003下对脚本程序的调试 如 :javascript
- [收藏]Javascript关于日期的各种技巧和方法总结[欢迎补充]
- 关于javascript的小东东
- javascript 关于表单的一些validation
- [Javascript]关于在ASP.NET环境中调用梅花雨的日历控件出错的解决办法