IE内存泄露与无法回收研究小结
2013-12-19 08:54
204 查看
一、内存泄露
之前确实看了很多资料,但这位大哥的话可谓画龙点睛,不是奉承他,一下子就打通了我的任督二脉,请看:
trarck 写道
IE下的内存泄露原因就是循环引用,IE的垃圾回收器不能很好处理这种引用。
会产生泄露的循环引用,只有孤立的DOM对象(脱离DOM树)。
孤立的DOM对象间的循环引用,孤立的DOM对象与JS对象的循环引用。
为什么是孤立的DOM对象呢?在离开页面时(刷新,跳转)会删除整个DOM树,在DOM树上的对象也会被删除,就算有循环引用,此时被打断。
孤立的DOM对象有:一、用JS创建但未加入DOM树。二、从DOM树中删除的。
所以避免泄露,就尽量不要让这样的DOM对象产生。
有时候这样对象又不可避免,那就不要让这样对像产生循环引用。
最常见的循环引用是由闭包产生,其执行环境中的变量(包括参数)引用了DOM对象。
看完了这段话,只会战战兢兢模仿示例的我立即就自创了一个新的例子。
示例1:
Java代码
<input type="button" value="leak" id="leak" onclick="location.reload();"/>
<script type="text/javascript"><!--
(function(){
var test=$('<div />')[0];
test.onclick=function(){};
var s=[];
for(var i=0;i<10000;i++){
s.push('aaaa');
}
test.expan=s.join('');
//$('body').append(test);
//孤立的DOM元素才会泄露
})();
//--></script>
特殊情况:iframe
测试工具为:sIEve-0.0.8
在iframe中刷新页面,页面中有很多泄露,每刷一次增加一倍;但最后刷新其父页面时所有的泄露都消失了。
而将iframe提出来单独测试(刷新),没有泄露。
二、内存回收
1、清除全局引用。道理很简单,只要全局引用存在浏览器不能释放对应的对象,因为在引用的生命周期内,对象随时可能被调用。
Html代码
<input type="button" value="TO GC" onclick="toGC()" />
<script type="text/javascript"><!--
function toGC(){
g.s=null;
}
var g={};
g.s=[];
for ( var i=0;i<100;i++){
g.s.push($('<div />')[0]);
}
//--></script>
如果不点击TO GC按钮,所创建的div永远都不会释放,直至页面unload。
2、各浏览器不同的内存释放机制
一个正常(无泄漏)的页面,当它unload(比如href指向about:blank)时,在不同的浏览器中内存释放情况并不相同。做了测试,使用某著名电子商务网站作测试对象。
IE7:不会出现显著释放,即使等1个小时也一样,内存依然很高;最小化窗口才会释放到几M的水准。
FireFox3:无论如何都不释放,目前还没找到方法(当然,关闭窗口除外)。
Chrome6:立即释放。
之前确实看了很多资料,但这位大哥的话可谓画龙点睛,不是奉承他,一下子就打通了我的任督二脉,请看:
trarck 写道
IE下的内存泄露原因就是循环引用,IE的垃圾回收器不能很好处理这种引用。
会产生泄露的循环引用,只有孤立的DOM对象(脱离DOM树)。
孤立的DOM对象间的循环引用,孤立的DOM对象与JS对象的循环引用。
为什么是孤立的DOM对象呢?在离开页面时(刷新,跳转)会删除整个DOM树,在DOM树上的对象也会被删除,就算有循环引用,此时被打断。
孤立的DOM对象有:一、用JS创建但未加入DOM树。二、从DOM树中删除的。
所以避免泄露,就尽量不要让这样的DOM对象产生。
有时候这样对象又不可避免,那就不要让这样对像产生循环引用。
最常见的循环引用是由闭包产生,其执行环境中的变量(包括参数)引用了DOM对象。
看完了这段话,只会战战兢兢模仿示例的我立即就自创了一个新的例子。
示例1:
Java代码
<input type="button" value="leak" id="leak" onclick="location.reload();"/>
<script type="text/javascript"><!--
(function(){
var test=$('<div />')[0];
test.onclick=function(){};
var s=[];
for(var i=0;i<10000;i++){
s.push('aaaa');
}
test.expan=s.join('');
//$('body').append(test);
//孤立的DOM元素才会泄露
})();
//--></script>
特殊情况:iframe
测试工具为:sIEve-0.0.8
在iframe中刷新页面,页面中有很多泄露,每刷一次增加一倍;但最后刷新其父页面时所有的泄露都消失了。
而将iframe提出来单独测试(刷新),没有泄露。
二、内存回收
1、清除全局引用。道理很简单,只要全局引用存在浏览器不能释放对应的对象,因为在引用的生命周期内,对象随时可能被调用。
Html代码
<input type="button" value="TO GC" onclick="toGC()" />
<script type="text/javascript"><!--
function toGC(){
g.s=null;
}
var g={};
g.s=[];
for ( var i=0;i<100;i++){
g.s.push($('<div />')[0]);
}
//--></script>
如果不点击TO GC按钮,所创建的div永远都不会释放,直至页面unload。
2、各浏览器不同的内存释放机制
一个正常(无泄漏)的页面,当它unload(比如href指向about:blank)时,在不同的浏览器中内存释放情况并不相同。做了测试,使用某著名电子商务网站作测试对象。
IE7:不会出现显著释放,即使等1个小时也一样,内存依然很高;最小化窗口才会释放到几M的水准。
FireFox3:无论如何都不释放,目前还没找到方法(当然,关闭窗口除外)。
Chrome6:立即释放。
相关文章推荐
- IE内存泄露与无法回收研究小结(持续增加中)
- IE内存泄露与无法回收研究小结
- IE内存泄露与无法回收研究小结
- 关于ADO内存泄露的今天的研究工作小结
- 关于IE下的内存回收研究.
- css hack IE兼容调试小结(Webstorm、VS2010),有图有真相,研究了一中午
- css hack IE兼容调试小结(Webstorm、VS2010),有图有真相,研究了一中午
- IE无法查看源文件原因及应用技巧
- 用jQuery解决input中placeholder值在ie中无法支持的问题
- IE8+兼容经验小结
- IE9无法输入文字、鼠标滚轮失效等问题之解决办法
- LoadRunner11录制无法打开IE的解决办法
- 研究一下FBrush,它是从TWinControl才有的属性(可能是因为需要句柄)——发现{$R *.dfm}在运行期执行,而且很有深意,读到属性后赋值还会触发事件,这些无法在VCL代码里直接看到
- JS在IE和FireFox之间常用函数的区别小结
- IE和Firefox下javascript的兼容写法小结
- bootstrap-datetimepicker在ie下报错:无法获取未定义或 null 引用的属性slice
- IE访问HTTPS链接下载文件,IE提示无法下载 博客分类: J2EE 原因: (1) 在IE6/7下,使用HTTPS下载/打开文件时,通过抓包发现文件已传输,但IE提示“Internet E
- magento后台无法通过IE登陆,但可以通过chrome和firefox登陆
- 【深入理解Java虚拟机】读后感:JVM垃圾回收小结
- 抛砖引玉:分享Win7 下 IE WebDriver 因保护模式无法启动的解决