循环引用如何导致JavaScript中的内存泄漏?
循环引用
当两个变量通过给每个对象赋予一个引用计数为1时,便形成了循环引用。在纯垃圾收集系统中,当所涉及的变量没有引用时,循环引用可能不是问题。声明的变量将被垃圾回收。在引用计数系统中,两个对象都不会被销毁,因为引用计数不能为零。
在使用引用计数和垃圾回收的混合系统中,由于系统无法识别循环引用,因此将发生内存泄漏。
示例
下面的示例显示了javascript对象和DOM对象之间的循环引用。javascript对象通过“expando”属性引用了DOM对象(Div)和Dom对象(Div),引用了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对象都是循环引用,但是当为javascript对象分配null时,这两个对象(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>