设置:
obj = object
obj.fun = function
obj.fun.ob = reference to obj
垃圾收集器会寻找这种类型的循环,还是泄漏?
设置:
obj = object
obj.fun = function
obj.fun.ob = reference to obj
垃圾收集器会寻找这种类型的循环,还是泄漏?
大多数 JavaScript 垃圾收集器都是标记和清除垃圾收集器,它们可以很好地处理这类事情。然而:
obj
在 IE6 和以前的版本中,如果是 COM 对象并且obj.fun
是 JavaScript 函数,则可能是内存泄漏。IE6 和之前的版本对 COM 对象使用 COM 垃圾收集器(它是一个引用计数器),对 JavaScript 对象使用 JavaScript 垃圾收集器(它是一个标记和清除收集器)。
在 IE7 中,仍然是内存泄漏,但在页面卸载时会被收集。但它仍然可能在页面启动时泄漏。
一个现代的、好的垃圾收集器应该能够检测到这样的循环引用。相反,他们的垃圾收集能力不受此类引用的阻碍(他们是否积极寻找此类案例是另一回事)。
受此问题影响的幼稚垃圾收集器的一个示例是仅对引用计数,并且仅当引用计数变为零时才进行垃圾收集。但是,由于您在上面指出的原因,这不是垃圾收集器通常的实现方式。
那里有许多更好的垃圾收集算法,并且本身就是一个大主题。
循环引用本身不会导致内存泄漏。这在一定程度上取决于您认为要包括的内存泄漏。目前,如果没有其他对象引用这些对象中的任何一个,那么它们将可用于 GC。但是,如果其他东西对一个有很强的引用,那么两者都将保持活动状态。
内存泄漏的通常原因是你在哪里设置
obj.fun = null;
并期望这会导致 fun 被收集,忘记 fun 有对 obj 的引用。当您忘记取消挂钩事件时,这正是发生的情况。