ie6的js实现是基于JScript和DOM ActiveX各种分离部件实现的,所以回收内存自然有些问题,下面简单介绍下内存泄漏
例一
- <html>
- <head><title>Queue Test 2</title>
- </head>
- <body>
- <script>
-
- (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没有交叉
例二
- <html>
- <head><title>Queue Test 2</title>
- </head>
- <body>
-
- <script>
-
- (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的匿名函数,导致匿名函数空间不能释放
例三
- <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>
-
- (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所写
- 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[n] === 'function') {
- d[n] = 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[n] === 'function') {
d[n] = null;
}
}
}
a = d.childNodes;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
purge(d.childNodes[i]);
}
}
}
入门介绍帖,很可能在ie6打完hotfix后测试结果不一样