Để thêm vào bobince câu trả lời, tôi đã thực hiện một số thử nghiệm với IE8.
tôi đã cố gắng gần như tất cả các ví dụ được cung cấp tại http://www.javascriptkit.com/javatutors/closuresleak/index.shtml
Không ai trong số họ được rò rỉ bộ nhớ nữa (ít nhất là không theo một cách nhận biết được), trừ các ví dụ mà loại bỏ nút con với các sự kiện vẫn còn gắn liền với chúng.
Loại ví dụ này tôi nghĩ giải thích rõ hơn là Douglas Crockford trong danh sách xếp hạng 2 của anh ấy.
Điều này vẫn rò rỉ bộ nhớ trên IE8 và nó khá dễ dàng để kiểm tra bằng cách chỉ cần chạy the test script và xem Windows Task Manager - Hiệu suất - PF Sử dụng. Bạn sẽ thấy PF Usage tăng thêm gần 1MB mỗi vòng lặp (rất nhanh).
Nhưng trong IE8 bộ nhớ được giải phóng trên trang dỡ bỏ (như điều hướng đến một trang mới hoặc tải lại cùng một trang) và rõ ràng cũng có khi hoàn toàn đóng trình duyệt. Vì vậy, để người dùng cuối cùng cảm nhận được rò rỉ bộ nhớ này trên IE8 (như giảm hiệu suất systerm), anh ta cần phải ở trên cùng một trang trong một thời gian dài, mà bây giờ nó có thể xảy ra thường xuyên với AJAX, nhưng trang này cũng cần phải thực hiện hàng trăm lần gỡ bỏ các phần tử con với sự kiện được đính kèm với chúng.
Kiểm tra Douglas Crockford đang nhấn mạnh trình duyệt với 10000 nút được thêm vào và sau đó xóa, điều đó thật tuyệt vời để hiển thị cho bạn vấn đề, nhưng trong thực tế tôi chưa bao giờ có trang xóa hơn 10 phần tử.INMHO thường nhanh hơn khi sử dụng display: none
thay vì xóa toàn bộ các nút, đó là lý do tại sao tôi không sử dụng số removeChild
nhiều.
Đối với bất cứ ai có thể quan tâm nhiều hơn trong bộ nhớ bị rò rỉ IE8 giải thích ở trên, tôi đã làm thử nghiệm khác và có vẻ như rò rỉ mem không hiển thị ở tất cả trong IE8 khi sử dụng innerHTML
ở vị trí của appendChild/removeChild
để thêm/xóa các phần tử con với các sự kiện đính kèm. Vì vậy, rõ ràng là Douglas Crockford purge function (gợi ý của anh ta để ngăn chặn rò rỉ bộ nhớ trong IE) là không cần thiết nữa trong IE8 ít nhất là khi sử dụng innerHTML
...
(EDITED nhờ 4esn0k bình luận dưới đây) ... hơn nữa Douglas Crockford purge function KHÔNG hoạt động ở tất cả trên IE8, trong mã của mình var a = d.attributes
trả về thuộc tính NO onclick
(hoặc bất kỳ thuộc tính khác onevent
) được thêm vào khi chạy trên IE8 (chúng được trả về trên IE7).
Douglas Crockford nói:
"Chức năng thanh lọc nên được gọi là trước khi tháo bất kỳ yếu tố, một trong hai theo phương pháp removeChild, hoặc bằng cách thiết lập các innerHTML tài sản."
tôi cung cấp ở đây là mã cho thử nghiệm:
<body>
<p>queuetest2 similar to the one provided by Douglas Crockford
at http://www.crockford.com/javascript/memory/leak.html
<br>but this one adds/removes spans using innerHTML
instead of appendChild/removeChild.</p>
<div id="test"></div>
<script>
/* ORIGINAL queuetest2 CODE FROM DOUGLAS CROCKFORD IS HERE
http://www.crockford.com/javascript/memory/queuetest2.html */
(function (limit, delay)
{
var n = 0;
var add = true;
function makeSpan(n)
{
var div = document.getElementById('test');
//adding also an inline event to stress more the browser
div.innerHTML = "<span onmouseover=\"this.style.color = '#00ff00';\">" + n + "</span>";
var s = div.getElementsByTagName('span')[0];
s.onclick = function(e)
{
s.style.backgroundColor = 'red';
alert(n);
};
return s;
}
function process(n)
{
if(add)
s = makeSpan(n);
else
s.parentNode.innerHTML = ""; //removing span by clearing the div innerHTML
add = !add;
}
function loop()
{
if (n < limit)
{
process(n);
n += 1;
setTimeout(loop, delay);
}
}
loop();
})(10000, 10);
</script>
</body>
+1: dài tìm kiếm perl này của trí tuệ. –
@Marco Demaio Hmm, http://ecmascript.stchur.com/blogcode/ie_innerhtml_memleak/leak.html vẫn rò rỉ trong IE9 ở cả hai tiêu chuẩn hoặc chế độ quirks (win7 64bit), Hãy chắc chắn sử dụng quá trình thám hiểm khi giám sát byte riêng tư .. sigh .. –
@AlexanderN: thực sự trên IE8 WXP trang bạn đề xuất không bị rò rỉ. Tôi sử dụng đơn giản "Windows Task Manager" ("Hiệu suất" tab) để xem nếu trang bị rò rỉ, trong trường hợp như vậy bạn sẽ thấy "PF sử dụng" ngày càng tăng. –