【发布时间】:2012-04-24 00:43:25
【问题描述】:
我知道事件监听器和对对象的引用会阻止垃圾收集器处理对象。我的问题是,放置在对象上的事件侦听器是否会侦听同一对象,以防止该对象被垃圾收集?
我问是因为这似乎发生在我身上。我打破了我对一个对象的所有引用,但是当它的计时器关闭时我仍然看到痕迹。同时,这似乎不应该阻止收集,因为它会创建已分配但不可引用的内存。
【问题讨论】:
标签: actionscript-3 garbage-collection event-listener
我知道事件监听器和对对象的引用会阻止垃圾收集器处理对象。我的问题是,放置在对象上的事件侦听器是否会侦听同一对象,以防止该对象被垃圾收集?
我问是因为这似乎发生在我身上。我打破了我对一个对象的所有引用,但是当它的计时器关闭时我仍然看到痕迹。同时,这似乎不应该阻止收集,因为它会创建已分配但不可引用的内存。
【问题讨论】:
标签: actionscript-3 garbage-collection event-listener
AVM2 垃圾收集器应该找到无法访问的对象。但是因为垃圾收集是非确定性的,所以很难依赖甚至测试这种行为——可能是垃圾收集器工作得很好,但是因为你有足够的可用 RAM,所以不需要运行标记和清除.
最好在完成对象后删除事件侦听器,即使它们来自对象本身(即循环引用)。为什么这是个好主意?因为你永远不知道垃圾收集器什么时候开始运行。如果您想要确定的行为,请始终以确定的方式删除侦听器,尤其是对于时间敏感的事件,如 TIMER 和 ENTER_FRAME,否则您正在运行的侦听器和运行的垃圾收集器之间创建竞争条件。垃圾收集器只定期运行。
一般来说,如果您想附加事件侦听器而不创建对对象的附加引用,请将 true 传递给 addEventListener() 的 useWeakReference 参数。但是,如果您想立即停止接收事件,您仍然需要在完成对象后立即手动分离事件侦听器。
【讨论】:
是的,这将阻止 GC 清理您的对象。尝试防止这种情况的一种巧妙方法是在添加侦听器时使用弱引用。
myobj.addEventListener(Event.EVENT, eventHandler, false, 0, true);
最后一个 true 标志将设置监听器使用弱对象引用。
最佳做法是跟踪并始终在清空您的对象之前删除所有活动的侦听器。
查看这篇精彩的博客文章以了解有关此主题的更多信息
http://gskinner.com/blog/archives/2006/06/as3_resource_ma.html
【讨论】: