浏览 4952 次
锁定老帖子 主题:有图片资源时的IE内存泄漏
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-15
最后修改:2009-07-22
ie7做了改进,会释放绑定在dom上的js对象(在页面重新加载时),使得js的gc可以回收资源(已经形成的循环引用占用的资源在当前页面无法得到回收),引用一篇文章的话说是这样的(http://www.iteye.com/topic/301496): "ie7的改进只是对于页面dom树上dom进行清除js引用,对于已经不在页面上但是还有js引用的ie7也是无能为力的 所以不能 LeakedDiv.parentElement.removeChild(LeakedDiv); 而要 LeakedDiv.expandoProperty=null; LeakedDiv.parentElement.removeChild(LeakedDiv); 才可以,其实即使这样使用Drip看还是有5个引用在LeakedDiv上,是不是泄漏不好说了,目前看来,ie上面较好的办法就是先别用removeChild了" 上面的说法可以从以下代码得到验证(重复刷新页面,内存不会回收,注释掉div01.parentNode.removeChild(div01)重刷页面,内存回收了...IE6依然是死都不回收) <div id="d01"><div id="d02">memoryTest</div></div> <script type="text/javascript"> function memoryTest(){ var a=[]; for(var i=0;i<100000;i++){ a.push('a'); } var div01=document.getElementById('d02'); div01.kk=function(){}; //此处产生一个闭包,此作用域资源得不到释放,divA不会销毁,循环引用产生 div01.parentNode.removeChild(div01); } memoryTest(); </script> 内存泄漏,还有一种情况,内存一直在涨,不回收,但是在最小化浏览器和刷新浏览器的时候,内存会回收一部分,我一直很诧异这个问题,内存泄漏怎么还能回收呢? 原来是这样的,分析: 这里div1.oo=obj2;obj2.oo=div1形成一个dom/js循环引用(dom引用图片资源,用滤镜方式),div1内存不会释放,滤镜如果没加载完,remove掉div1,滤镜不会消耗内存,如果滤镜已经加载完毕,则会消耗内存,关键在于此处,滤镜消耗的内存不会得到释放,但是在刷新浏览器和最小化浏览器时内存会得到释放. 猜测ie7 dom引擎渲染页面是这么做的,在最小化浏览器的时候ie7会遍历一下dom树,将不在dom树的图片资源清除出去,不管拥有图片资源的dom是否被引用,限于以滤镜方式加载的图片,以img src加载方式的图片复杂一些,刷新不会回收内存,但在最小化时会释放一部分内存 代码如下: <body> <input type="button" value="dom增大内存" onclick="domMemory()"/> <input type="button" value="dom清除内存" onclick="clearMemory()"/> </body> <script> //重复的创建销毁dom元素不会导致内存泄漏 或者 内存不回收 var dinAry=[]; var obj1={}; obj1.ary=[]; for(var i=0;i<10000;i++){ obj1.ary.push(i.toString()); } function domMemory(){ for(var i=0;i<200;i++){ var div1=document.createElement("div"); var css1='width:200px;height:200px;filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale, src="img/a.png");"'; div1.style.cssText = css1; div1.setAttribute("style",css1); var obj2={}; div1.oo=obj2; //引用一个全局变量 obj2.oo=div1 document.body.appendChild(div1); dinAry.push(div1); // var fun1=function(){} } setTimeout(clearMemory,1000); //确保图片加载完成,否则不会占用内存 } function clearMemory(){ var temp; while(temp = dinAry.pop()){ document.body.removeChild(temp); } } </script> 网名: 天堂左我往右 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-06-16
re啊。。。BS IE的引用计数。。。
|
|
返回顶楼 | |
发表时间:2009-06-18
恩 开发web application 的 要十分注意这个问题
|
|
返回顶楼 | |
发表时间:2009-06-19
IE下发现的bug真不少,尤其是IE6。文章分析的很翔实,受益匪浅。谢谢
|
|
返回顶楼 | |
发表时间:2009-06-20
谢谢捧场哈
|
|
返回顶楼 | |
发表时间:2009-06-22
手动试了一下,在ie6下,点击dom增大内存,内存增加,点击dom清除内存,内存尚无减少....是不是我有那个地方错了?
|
|
返回顶楼 | |
发表时间:2009-06-26
清除内存 那个按钮其实没用,只是为了测试在IE7下,不在dom树中的节点会造成内存泄漏...
感谢捧场哈 |
|
返回顶楼 | |
发表时间:2009-07-09
上面两种 ie8 刷新后就回去了.
|
|
返回顶楼 | |
发表时间:2009-07-10
ie8还是不错的...
期待后ie时代浏览器,哈哈 |
|
返回顶楼 | |