您的位置:首页 > Web前端 > JavaScript

关于ie6的DOM JScript内存泄漏介绍

2010-02-24 11:12 337 查看
ie6的js实现是基于JScript和DOM ActiveX各种分离部件实现的,所以回收内存自然有些问题,下面简单介绍下内存泄漏
例一

Js代码
<html> <head><title>Queue Test 2</title> </head> <body> <script> /*global setTimeout */ (function (limit, delay) { var queue = new Array(10); var n = 0; function makeSpan(n) { var s = document.createElement('span'); document.body.appendChild(s); var t = document.createTextNode(' ' + n); s.appendChild(t); return s; } function process(n) { queue.push(makeSpan(n)); var s = queue.shift(); if (s) { s.parentNode.removeChild(s); } } function loop() { if (n < limit) { process(n); n += 1; setTimeout(loop, delay); } } loop(); })(10000, 10); </script> </body> </html>
<html>
<head><title>Queue Test 2</title>
</head>
<body>
<script>
/*global setTimeout */
(function (limit, delay) {
var queue = new Array(10);
var n = 0;

function makeSpan(n) {
var s = document.createElement('span');
document.body.appendChild(s);
var t = document.createTextNode(' ' + n);
s.appendChild(t);
return s;
}

function process(n) {
queue.push(makeSpan(n));
var s = queue.shift();
if (s) {
s.parentNode.removeChild(s);
}
}

function loop() {
if (n < limit) {
process(n);
n += 1;
setTimeout(loop, delay);
}
}

loop();
})(10000, 10);
</script>
</body>
</html>

在ie6上面执行毫无问题,没有泄露,最多10个span,多了就remove,DOM和JScript没有交叉

例二

Js代码
<html> <head><title>Queue Test 2</title> </head> <body> <script> /*global setTimeout */ (function (limit, delay) { var queue = new Array(10); var n = 0; function makeSpan(n) { var s = document.createElement('span'); document.body.appendChild(s); var t = document.createTextNode(' ' + n); s.appendChild(t); s.onclick = function (e) { s.style.backgroundColor = 'red'; alert(n); }; return s; } function process(n) { queue.push(makeSpan(n)); var s = queue.shift(); if (s) { s.parentNode.removeChild(s); } } function loop() { if (n < limit) { process(n); n += 1; setTimeout(loop, delay); } } loop(); })(10000, 10); </script> </body> </html>
<html>
<head><title>Queue Test 2</title>
</head>
<body>

<script>
/*global setTimeout */
(function (limit, delay) {
var queue = new Array(10);
var n = 0;

function makeSpan(n) {
var s = document.createElement('span');
document.body.appendChild(s);
var t = document.createTextNode(' ' + n);
s.appendChild(t);
s.onclick = function (e) {
s.style.backgroundColor = 'red';
alert(n);
};
return s;
}

function process(n) {
queue.push(makeSpan(n));
var s = queue.shift();
if (s) {
s.parentNode.removeChild(s);
}
}

function loop() {
if (n < limit) {
process(n);
n += 1;
setTimeout(loop, delay);
}
}

loop();
})(10000, 10);
</script>
</body>
</html>

执行时候,打开任务管理器,大概每秒PF上升1M,原因是DOM元素span握有带closure的匿名函数,导致匿名函数空间不能释放

例三

Js代码
<html> <head><title>Queue Test 2</title> </head> <body> <p> Queue Test 2 adds an event handler to each span. See <a href="http://www.crockford.com/javascript/memory/leak.html">http://www.crockford.com/javascript/memory/leak.html</a> </p> <script> /*global setTimeout */ (function (limit, delay) { var queue = new Array(10); var n = 0; function makeSpan(n) { var s = document.createElement('span'); document.body.appendChild(s); var t = document.createTextNode(' ' + n); s.appendChild(t); s.onclick = function (e) { s.style.backgroundColor = 'red'; alert(n); }; return s; } function process(n) { queue.push(makeSpan(n)); var s = queue.shift(); if (s) { s.onclick=null; s.parentNode.removeChild(s); } } function loop() { if (n < limit) { process(n); n += 1; setTimeout(loop, delay); } } loop(); })(10000, 10); </script> </body> </html>
<html>
<head><title>Queue Test 2</title>
</head>
<body>
<p>
Queue Test 2 adds an event handler to each span. See <a href="http://www.crockford.com/javascript/memory/leak.html">http://www.crockford.com/javascript/memory/leak.html</a>
</p>
<script>
/*global setTimeout */
(function (limit, delay) {
var queue = new Array(10);
var n = 0;

function makeSpan(n) {
var s = document.createElement('span');
document.body.appendChild(s);
var t = document.createTextNode(' ' + n);
s.appendChild(t);
s.onclick = function (e) {
s.style.backgroundColor = 'red';
alert(n);
};
return s;
}

function process(n) {
queue.push(makeSpan(n));
var s = queue.shift();
if (s) {
s.onclick=null;
s.parentNode.removeChild(s);
}
}

function loop() {
if (n < limit) {
process(n);
n += 1;
setTimeout(loop, delay);
}
}

loop();
})(10000, 10);
</script>
</body>
</html>

手动将带closure的匿名函数null后,再remove,内存无泄漏,最后有一purge函数,为Douglas Crockford所写

Js代码
function purge(d) { var a = d.attributes, i, l, n; if (a) { l = a.length; for (i = 0; i < l; i += 1) { n = a[i].name; if (typeof d === 'function') { d = null; } } } a = d.childNodes; if (a) { l = a.length; for (i = 0; i < l; i += 1) { purge(d.childNodes[i]); } } }
function purge(d) {
var a = d.attributes, i, l, n;
if (a) {        l = a.length;
for (i = 0; i < l; i += 1) {
n = a[i].name;
if (typeof d
=== 'function') {
d
= null;
}
}
}
a = d.childNodes;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
purge(d.childNodes[i]);
}
}
}

入门介绍帖,很可能在ie6打完hotfix后测试结果不一样
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: