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 次瀏覽

啟動您的 職業生涯

透過完成課程獲得認證

開始學習
廣告