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>

更新于:2019年7月30日

445 次浏览

启动您的 职业生涯

通过完成课程获得认证

开始学习
广告