JavaScript 中的循环引用如何导致内存泄漏?
循环引用
循环引用是指当两个变量相互引用时形成的,从而使每个对象的引用计数为 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 对象)都将难以确定它们引用的对象是 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>
广告