循环引用如何导致 JavaScript 中的内存泄漏?
javascriptobject oriented programmingprogramming
循环引用
当两个变量相互引用时,就会形成循环引用,从而为每个对象赋予 1 个引用计数。在纯垃圾收集系统中,当所涉及的变量没有引用时,循环引用可能不是问题。在这种情况下,声明的变量将被垃圾收集。在引用计数系统中,两个对象都不会被销毁,因为引用计数不能为零。
在使用引用计数和垃圾收集的混合系统中,由于系统无法识别循环引用,因此会发生内存泄漏。
示例
以下示例显示了 javascript 对象和 DOM 对象之间的循环引用。javascript 对象引用了 DOM 对象(Div),而 Dom 对象(Div)通过"expando"属性引用了 javascript 对象(obj)。由于两个对象相互引用,因此无法销毁任何对象,从而导致内存泄漏。
<html> <body> <script> window.onload = function(){ var obj=document.getElementById("DivElement"); document.getElementById("DivElement").expandoProperty=obj; obj.String=new Array(1000).join(new Array(2000); }; </script> </body> </html>
避免内存泄漏
在下面的例子中,最初 javascript 对象和 DOM 对象都处于循环引用中,但是当将 null 分配给 javascript 对象时,这两个对象(javascript 和 DOM 对象)都会陷入困境,无法确定它们引用的是谁,即 javascript 对象是引用 null 还是 DOM 对象,从而打破循环引用。
示例
<html> <body> <script> window.onload = function(){ var obj=document.getElementById("DivElement"); document.getElementById("DivElement").expandoProperty=obj; obj.String=new Array(1000).join(new Array(2000); obj = null // this breaks circular reference }; </script> </body> </html>