调用removeChild()时Flex中的垃圾收集 - 管理竞争条件

时间:2008-10-19 09:20:33

标签: flex actionscript garbage-collection

我在Flex中有一个'框架',用于加载和销毁子节'部分',它们是模块类的实例。它们中包含大量的Web服务和动画,是面向公众的网站的一部分。

在我从屏幕上删除一个部分之前,我在实例上调用了一个'hideSection()'接口方法。在这个方法中,我淡出任何控件,如果该部分想要阻止自己被关闭,则返回false。目前它还会停止运行任何Timer实例。

问题在于,即使从舞台上移除了部分对象,也可能会有一些悬而未决的事情发生。例如,我可能会在effectEnded触发某些内容的情况下运行效果,或者可能是一个缓慢的Web服务请求可能会超时并导致弹出错误。

由于垃圾收集器的工作方式 - 有时候对象对象会很快被杀掉,有时会被杀死。我试图尽量减少一个部分关闭后发生的坏事。

我想出了以下可能的解决方案。想知道是否有更好的一个。

  • 设置_disposed属性,设置为true。在任何可能有不良行为的事件处理程序内(在该部分关闭后)我只会说if (_disposed) { return; }
  • 也可能需要实现'IDisposable'接口,如.NET。

这真的是我唯一的选择 - 或者我可以以某种方式加快垃圾收集。如果有效果仍在运行,垃圾收集是否会发生?

我也很好奇我是否应该把事情设置为_null,尤其是计时器。或者只是停止()一个计时器,如果没有任何参考,它就会被垃圾收集。

2 个答案:

答案 0 :(得分:1)

http://gskinner.com/talks/resource-management/

这是关于垃圾收集的盛大皮肤。在幻灯片32周围,他谈到了他的看门人系统。你可以阅读然后抓住他的源文件。

还要确保你熟悉他关于flash 9的垃圾收集的讨论: http://www.gskinner.com/blog/archives/2008/04/failure_to_unlo.html

具体看这部分:

  

解决方法和策略   您现在可以采取四项主要措施来解决这些问题:

     
      
  1. 确保始终在要加载到较大应用程序中的内容中删除计时器和enterframe事件侦听器。另外,尽可能避免使用舞台监听器,并在完成后立即将其删除。

  2.   
  3. 在SWF中公开一个标准API,允许其他SWF告诉它清理并停止执行。这样,加载应用程序可以在卸载任何内容之前调用此方法(在try / catch块中)。我会建议一个.halt()方法,由一个侦听器支持,通过sharedEvents“停止”事件。

  4.   
  5. 您可以从子域加载内容SWF。这将隐式将其置于安全沙箱中。

  6.   
  7. 将内容加载到主应用程序中分层的div中。这不是一个很好的选择,但它几乎解决了所有问题。

  8.   

答案 1 :(得分:0)

您可以删除hideSection()方法中的所有活动事件侦听器。

removeEventListener(this, listenerFunction, eventType);

如果您使用weak reference添加了事件侦听器,并且没有其他引用,那么应该对侦听器的目标进行垃圾回收。