挑战超难问题,寻高手帮助解决 一个典型的 半透明层 内存泄露问题

DBXP 2007-11-09 09:13:52
挑战超难问题,寻高手帮助解决 一个典型的 半透明层 内存泄露问题
问题描述:javascript动态添加一个半透明的DIV标签和一个关闭按钮,点击关闭按钮后内存无法释放,反复几次内存无限制上涨。

具体测试:(必须在IE下测试才能发现问题)
1、依次执行“添加”“删除”“释放内存”,如此反复多次,发现内存可以正常释放。
2、依次执行“添加”“从内部删除”“释放内存”,如此反复多次,发现内存泄露无限制增长。


源代码如下:

<html>
<head>
<script language="javascript">
var arr = new Array();
function c()
{
var div = document.createElement("DIV");
document.body.appendChild(div);
div.innerHTML = '<input type="button" value="从内部删除" onclick="f()"/><div style="position:absolute;top:110;left:110;width:1000px;height:1000px;-moz-opacity:0.07;filter:alpha(opacity=7);background-color:#000000"></div>';
arr.push(div);
abcd.innerText = arr.length;
}

function f()
{
var tmp = arr.pop();
while(tmp!=null)
{
// for(var i = tmp.childNodes.count-1; i >=0 ; i--)
// {
// tmp.removeChild(tmp.childNodes[i]);
// }
document.body.removeChild(tmp);
tmp = arr.pop();
}
abcd.innerText = arr.length;
}

function g()
{
CollectGarbage();
}

</script>
</head>
<body>

<input type="button" value="添加" onclick="c();" />
<input type="button" value="删除" onclick="f();" />
<input onclick="g()" type="button" value="释放内存" />
<div id="abcd"></div>
典型的 半透明层 内存泄露问题:<br />
测试:(必须在IE下测试才能发现问题)<br />
1、依次执行“添加”“删除”“释放内存”,如此反复多次,发现内存可以正常释放。<br />
2、依次执行“添加”“从内部删除”“释放内存”,如此反复多次,发现内存泄露无限制增长。
</body>
</html>

...全文
660 60 打赏 收藏 转发到动态 举报
写回复
用AI写文章
60 条回复
切换为时间正序
请发表友善的回复…
发表回复
asker100 2011-11-24
  • 打赏
  • 举报
回复
mark
buybyetoo 2011-01-11
  • 打赏
  • 举报
回复
function f()
{
var tmp = arr.pop();
while(tmp!=null)
{
// for(var i = tmp.childNodes.count-1; i >=0 ; i--)
// {
// tmp.removeChild(tmp.childNodes[i]);
// }
tmp.innerHTML = null ;
document.body.removeChild(tmp);
tmp = arr.pop();
}
abcd.innerText = arr.length;
}

把innerHtml置为null,内存就释放了
buybyetoo 2011-01-11
  • 打赏
  • 举报
回复
function f()
{
var tmp = arr.pop();
while(tmp!=null)
{
// for(var i = tmp.childNodes.count-1; i >=0 ; i--)
// {
// tmp.removeChild(tmp.childNodes[i]);
// }
tmp.innerHTML = null ;
document.body.removeChild(tmp);
tmp = arr.pop();
}
abcd.innerText = arr.length;
}
huihui0103 2008-07-05
  • 打赏
  • 举报
回复
mark 收藏一下
seahi 2008-07-03
  • 打赏
  • 举报
回复
mark,此贴绝对是好贴。
dbwang 2008-03-25
  • 打赏
  • 举报
回复
将这个帖子收藏了!
sunyujia 2008-03-08
  • 打赏
  • 举报
回复
做个记号
DBXP 2007-11-21
  • 打赏
  • 举报
回复

搞来搞去问题解决了

感谢大家的热情帮助和积极参与,搞来搞去问题终于解决了,暂时告一段落。解决办法说来也简单,具体如下:


问题代码概要:下面代码中 b 是主要占用内存最多的

<div id="a">
<div id="b" style="你的透明度代码"></div>
</div>


问题关键点,设置透明度的 DIV 标签中千万不能嵌套任何内容(普通文本也不行,连空格都不要有)。
释放内存的问题,只要设置
a.innerText = "";
就一切搞定了,至少我测试的时候是 b 占用的大量内存可以正确释放。

欢迎大家继续测试,任何相关问题请发到这个帖子里方便大家学习您的解决方法。

Good luck!
muxrwc 2007-11-15
  • 打赏
  • 举报
回复
框架等有大量的时间在看,现在家里上不了网T_

偶说说这个方法。就是想学下DOM 标准的 Range对象。。偶对它一直很陌生滴说。。。
qf521lx 2007-11-15
  • 打赏
  • 举报
回复
insertAdjacentHTML 不能往tr中写?
DBXP 2007-11-14
  • 打赏
  • 举报
回复
回41楼(meizz)

你说的方法确实可以释放内存,但是却多使用了一个<div id="mm"></div>标签,感觉不是很爽,而且当我们需要动态生成的时候不一定能够提前预知有这样一个标签。
gzdiablo 2007-11-14
  • 打赏
  • 举报
回复
不好意思搞错人了 应该是叫muxrwc去研究一下
btbtd 2007-11-13
  • 打赏
  • 举报
回复
insertAdjacentHTML 存在兼容问题...
meizz 2007-11-13
  • 打赏
  • 举报
回复
用 document.createElement() 创建的对象都会在内存里存在一个引用,并且这个引用是不会被释放的,所以一般这种大量的HTML注入操作推荐你使用另一个方法
insertAdjacentHTML!

<html>
<head>
<script language="javascript">

if(typeof(HTMLElement)!="undefined" && !window.opera)
{
HTMLElement.prototype.insertAdjacentHTML=function(where, html)
{
var e=this.ownerDocument.createRange();
e.setStartBefore(this);
e=e.createContextualFragment(html);
this.insertAdjacentElement(where,e);
};
HTMLElement.prototype.insertAdjacentElement=function(where, e)
{
switch (where)
{
case 'beforeBegin': this.parentNode.insertBefore(e, this);break;
case 'afterBegin': this.insertBefore(e, this.firstChild); break;
case 'beforeEnd': this.appendChild(e); break;
case 'afterEnd':
if(!this.nextSibling) this.parentNode.appendChild(e);
else this.parentNode.insertBefore(e, this.nextSibling); break;
}
};
};
var arr = new Array();
function c()
{
var id = "mm_"+ (new Date().getTime().toString(36));
document.getElementById("mm").insertAdjacentHTML("beforeEnd", '<div id="'+ id +'"><input type="button" value="从内部删除" onclick="f()"/><div style="position:absolute;top:110;left:110;width:1000px;height:1000px;-moz-opacity:0.07;filter:alpha(opacity=7);background-color:#000000"></div></div>')
arr[arr.length] = document.getElementById(id);
abcd.innerHTML = arr.length;
}

function f()
{
arr.length = 0;
document.getElementById("mm").innerHTML = "";
}

function g()
{
CollectGarbage();
}

</script>
</head>
<body>

<input type="button" value="添加" onclick="c();" />
<input type="button" value="删除" onclick="f();" />
<input onclick="g()" type="button" value="释放内存" />
<div id="abcd"></div>
典型的 半透明层 内存泄露问题:<br />
测试:(必须在IE下测试才能发现问题)<br />
1、依次执行“添加”“删除”“释放内存”,如此反复多次,发现内存可以正常释放。<br />
2、依次执行“添加”“从内部删除”“释放内存”,如此反复多次,发现内存泄露无限制增长。
<div id="mm"></div>
</body>
</html>
btbtd 2007-11-13
  • 打赏
  • 举报
回复
哦哦, 不好意思, 态度有点过了..可能学的杂七杂八东西太多了...
btbtd 2007-11-13
  • 打赏
  • 举报
回复
哦, 研究...你没开玩笑吧,
现在各个浏览器有什么东西基本上我可以倒背出来...
系统化的东西, 我现在可以一个人写个CMS系统...
gzdiablo 2007-11-13
  • 打赏
  • 举报
回复
ext里面出现过类似的insertAdjacentHTML的代码
btbtd最好研究一下各个js框架 很有帮助的
还有FF提供了大量的对象原型供开发者扩展 真的很方便.
btbtd 2007-11-13
  • 打赏
  • 举报
回复
哦, 俺看到一长串的代码一般不看...
你那个树能不能修修, 用Opera 9+ 根本看不了导航,
muxrwc 2007-11-13
  • 打赏
  • 举报
回复
如获至宝。。。偶加上翻译,转到偶blog里去。。。(有空在转:D)

HTMLElement.prototype.insertAdjacentHTML = function(where, html) {
//Meizz
var e = this.ownerDocument.createRange();
e.setStartBefore(this);
e = e.createContextualFragment(html);
this.insertAdjacentElement(where, e);
};

HTMLElement.prototype.insertAdjacentElement = function(where, e) {
//Meizz
switch (where) {
case 'beforeBegin' : this.parentNode.insertBefore(e, this); break;
case 'afterBegin' : this.insertBefore(e, this.firstChild); break;
case 'beforeEnd' : this.appendChild(e); break;
case 'afterEnd' :
if (!this.nextSibling) this.parentNode.appendChild(e);
else this.parentNode.insertBefore(e, this.nextSibling);
break;
}
};
meizz 2007-11-13
  • 打赏
  • 举报
回复
兼容性的问题处理我已经在代码里写明了!
加载更多回复(40)

87,925

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧