这种模式如何获得循环引用

时间:2018-04-19 23:22:30

标签: javascript memory-leaks

所有

我对Javascript内存管理很陌生,目前正在阅读:

https://www.ibm.com/developerworks/library/wa-memleak/wa-memleak-pdf.pdf

在本文中,对于清单5,解释说:

  

在清单5中,您会看到一个闭包,其中有一个JavaScript对象(obj)   包含对DOM对象的引用(由id&#34引用;元素")。   反过来,DOM元素引用了JavaScript obj。该   在JavaScript对象和DOM之间产生循环引用   对象导致内存泄漏。

任何人都可以给我一些关于这个模式如何构建循环引用并导致内存泄漏的更多细节(图表将受到高度赞赏)?特别是这部分:

  

反过来,DOM元素引用了JavaScript obj。



help(np.where())

document.write("Program to illustrate memory leak via closure");

window.onload = function outerFunction() {
    var obj = document.getElementById("element");

    obj.onclick = function innerFunction() {
        alert("Hi! I will leak");
    };

    obj.bigString = new Array(1000).join(new Array(2000).join("XXXXX"));
    // This is used to make the leak significant
};




1 个答案:

答案 0 :(得分:1)

只有在您计划在某个时候删除按钮元素时才会出现问题。

循环引用的发生是因为outerFunction引起的闭包:innerFunction按钮的click事件监听器将引用obj这个按钮。因此删除按钮不会生效,因为对它的引用将始终存在(在其自己的单击事件侦听器内),从而阻止垃圾收集器。

当对象不再具有对它的任何引用时,垃圾收集器会在JS中删除对象。通过执行以下操作从DOM中删除按钮,例如:

document.getElementById("element").remove();

将从DOM中删除对该按钮的引用,但是垃圾收集器将无法删除它,因为innerFunction内的该按钮会有另一个引用obj(其中包含参考按钮)。

这里的循环引用是为了删除/销毁innerFunction,必须首先销毁该按钮,并且为了删除/销毁该按钮,必须删除对它的所有引用,包括内部{ {1}}。

注意:在最近的浏览器中shouldn't worry关于那些导致内存泄漏的事件侦听器。