在AS3强制垃圾收集?

时间:2008-10-10 17:30:44

标签: flex flash actionscript-3 garbage-collection

是否可以在ActionScript 3.0中以编程方式强制执行完整的垃圾回收?

假设我已经创建了一堆带有eventListeners的Display对象,并且已经删除了一些DO,一些eventListener已被触发和删除等等...有没有办法强制垃圾收集运行和收集一切可以收集?

8 个答案:

答案 0 :(得分:25)

是的,这是可能的,但这通常是一个坏主意。 GC应该更好地了解何时是一个比你应该运行的好时机,除了一个非常具体的情况,就像你刚刚使用500MB内存而你需要尽快恢复它,你不应该调用GC自己。

在Flash 10中,您可以调用System.gc()方法(但请不要,请参阅上文) - 请记住,System.gc()仅适用于Flash Player 10+的调试版本。

在Flash 9中,有一种不受支持的方法可以通过奇怪的LocalConnection命令强制它,但它可能无法在所有版本中使用。请参阅Grant Skinner的this post

答案 1 :(得分:15)

有一个新的API告诉GC它可能是一个“相对好的时刻”来收集。

请参阅Adobe API文档 System.pauseForGCIfCollectionImminent

在播放器版本11中引入该方法后不久,这个Adobe blog post

该方法采用“迫近”的论点;基本上,如果你真的希望收集器运行,你输入一个较小的数字(接近0.0),即使自上次收集以来没有太多活动(目前通过字节分配测量),你输入的数量很大(接近1.0)如果你只是想要收集暂停发生,如果我们已经接近收集会发生的点。

这里的动机是针对例如想要在GC发生少量转移点的游戏,例如:在游戏中改变等级时执行GC,而不是在玩家开始探索关卡后两秒钟。

一个非常重要的细节:Release和Debugger Flash Runtimes都支持这个新API。这使它优于调用System.gc()。

答案 2 :(得分:8)

对于所有当前发布的版本,System.gc()仅适用于Flash播放器和ADL(AIR应用程序的调试环境)的调试版本。 Flash player 10 beta目前可以用于各种风格。

我同意Davr,这是一个坏主意。运行时通常比你有更好的想法。

另外,垃圾收集器如何工作的细节是一个实现细节,可能会在Flash播放器版本之间发生变化。所以今天运作良好并不能保证将来能够很好地运作。

答案 3 :(得分:3)

正如其他人所说:不要手动尝试GC,有黑客攻击,但这不安全。

你应该尽可能地尝试回收对象 - 你会节省大量的内存。

这可以应用于BitmapDatas(清除和重用),粒子(从显示中删除和重用)。

答案 4 :(得分:3)

我对那些说你永远不应该手动操作GC的人发表评论。我习惯于使用C ++进行手动内存管理,而且我更喜欢使用sharedptr而不是GC,但无论如何。

有一个特定的案例,我找不到另一种解决方案而不是GC。请考虑:我有一个DataCache类,它的工作方式是保留某些方法调用的结果对象,以便在刷新/接收数据时发送更新的事件。刷新缓存的方式是我只清除它的所有结果并发送导致任何剩余侦听器重新请求其数据的事件,超出范围的侦听器不应重新请求清除不需要的结果。但显然,如果我不能强制所有仍然悬挂等待GC的侦听器立即清理,然后再发出“再问一次数据”事件,那些悬空的听众将不必要地再次请求数据。因为我无法删除事件,因为AS3没有析构函数,所以我看不到另一个简单的解决方案,而不是强迫GC确保不再有悬空的侦听器。

(编辑)除此之外,我无法使用removeEventListener进行绑定,例如在mxml中设置(使用我自己处理remoteobj的自定义DataCacher类)

<mx:DataGrid id="mygrid" dataProvider="{DataCacher.instance().result('method').data}" ... />

当关闭包含此数据网格的弹出窗口时,您会期望绑定被销毁。显然他们生活在一起。嗯,当对象被标记时,不应该从对象中弹性销毁所有绑定(意味着eventlisteners),因为最后一个引用被删除了。那对我来说有点解决了这个问题。

至少这就是为什么我认为,我仍然是Flex的初学者,所以任何想法都会受到赞赏。

答案 5 :(得分:3)

try {
    new LocalConnection().connect('foo');
    new LocalConnection().connect('foo');
} catch (e:*){
    trace("Forcing Garbage Collection :"+e.toString());
}

答案 6 :(得分:0)

如果必须,调用gargabe收集器可能会有用......所以,你必须小心如何以及何时这样做,但毫无疑问,有时候需要它。

例如,如果您有一个模块化的应用程序,当您从一个视图更改为另一个视图时,所有已删除的对象可能代表大量的内存,应该尽可能快地提供,您只需要控制您正在处理的变量和参考。

答案 7 :(得分:0)

回收利用并没有多大帮助。我使用了一个装载器,每500ms重复加载相同的jpg。任务经理仍然报告内存不停增加。

这里尝试并证明了解决方案。

http://simplistika.com/as3-garbage-collection/