【问题标题】:Actionscript 3: Do self event listeners prevent an object from being garbage collected?Actionscript 3:self 事件侦听器是否会阻止对象被垃圾收集?
【发布时间】:2012-04-24 00:43:25
【问题描述】:

我知道事件监听器和对对象的引用会阻止垃圾收集器处理对象。我的问题是,放置在对象上的事件侦听器是否会侦听同一对象,以防止该对象被垃圾收集?

我问是因为这似乎发生在我身上。我打破了我对一个对象的所有引用,但是当它的计时器关闭时我仍然看到痕迹。同时,这似乎不应该阻止收集,因为它会创建已分配但不可引用的内存。

【问题讨论】:

    标签: actionscript-3 garbage-collection event-listener


    【解决方案1】:

    不,但是。

    AVM2 垃圾收集器应该找到无法访问的对象。但是因为垃圾收集是非确定性的,所以很难依赖甚至测试这种行为——可能是垃圾收集器工作得很好,但是因为你有足够的可用 RAM,所以不需要运行标记和清除.

    最好在完成对象后删除事件侦听器,即使它们来自对象本身(即循环引用)。为什么这是个好主意?因为你永远不知道垃圾收集器什么时候开始运行。如果您想要确定的行为,请始终以确定的方式删除侦听器,尤其是对于时间敏感的事件,如 TIMER 和 ENTER_FRAME,否则您正在运行的侦听器和运行的垃圾收集器之间创建竞争条件。垃圾收集器只定期运行。

    一般来说,如果您想附加事件侦听器而不创建对对象的附加引用,请将 true 传递给 addEventListener()useWeakReference 参数。但是,如果您想立即停止接收事件,您仍然需要在完成对象后立即手动分离事件侦听器。

    【讨论】:

    • 我不太担心仍在触发的事件。我更担心内存在某个时候被释放。但是,我确实看到 CPU 部门的好处可能是巨大的。谢谢。
    【解决方案2】:

    是的,这将阻止 GC 清理您的对象。尝试防止这种情况的一种巧妙方法是在添加侦听器时使用弱引用。

     myobj.addEventListener(Event.EVENT, eventHandler, false, 0, true);
    

    最后一个 true 标志将设置监听器使用弱对象引用。

    最佳做法是跟踪并始终在清空您的对象之前删除所有活动的侦听器。

    查看这篇精彩的博客文章以了解有关此主题的更多信息

    http://gskinner.com/blog/archives/2006/06/as3_resource_ma.html

    【讨论】:

    • 感谢您的快速回复。我读了那篇文章,但我仍然有点困惑。当垃圾收集器进行标记清除阶段时,它将在哪里标记我的对象?某处是否有一个事件侦听器列表,提供对事件附加/侦听的对象的引用?
    • 当你将监听器添加到一个对象时,你正在向它添加一个引用
    • -1。这不会阻止 GC 收集您的实例。 developria.com/2010/08/rethinking-addeventlistener-an.html
    • @AmyBlankenship 是的,因此他的对象不会被 GC 处理。具有侦听器的对象还包含被调用的方法。使用弱 ref 将阻止这种情况的发生,这似乎是它的完美用例?
    • 所以在基于引用的垃圾收集的情况下,对象永远不会被GC,因为它是它自己的监听器和调度器。但是,由于标记清除它会,因为所涉及的任何内容都没有从文档根目录到它的引用路径。这里最大的问题是,看起来大多数人,包括 45 分钟前的我自己,都不知道基于标记清除的垃圾收集。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 2012-12-20
    相关资源
    最近更新 更多