在ActionScript 3.0中,是否可以编程方式强制运行完整的垃圾回收?
假设我已经创建了一堆带有事件监听器的显示对象(Display objects),其中一些显示对象已被删除,一些事件监听器已被触发和删除等等... 是否有一种方法可以强制运行垃圾回收,并收集所有可回收的内容?
在ActionScript 3.0中,是否可以编程方式强制运行完整的垃圾回收?
假设我已经创建了一堆带有事件监听器的显示对象(Display objects),其中一些显示对象已被删除,一些事件监听器已被触发和删除等等... 是否有一种方法可以强制运行垃圾回收,并收集所有可回收的内容?
是的,这是可能的,但通常不是一个好主意。垃圾回收器应该比你更清楚何时运行是一个好时机,除非有一个非常特定的情况,比如你刚使用了500MB的内存并且需要尽快获得回收,否则就不应该自己调用垃圾回收。
在Flash 10中,有一个System.gc()
方法可以调用(但请不要,见上文)-请记住System.gc()仅适用于Flash player 10+的调试版本。
在Flash 9中,有一种不支持的方式可以通过奇怪的LocalConnection命令进行强制处理,但它可能不能在所有版本中工作。请参阅Grant Skinner的此文章。
现在有一个新的API,用于告诉垃圾回收器它可能是一个“相对不错的时刻”进行回收。
请参阅Adobe API文档中的System.pauseForGCIfCollectionImminent
还有这个来自Adobe博客文章的链接:Adobe blog post,介绍了该方法在Player 11版本推出后不久的情况。
该方法需要一个“即将发生”的参数;基本上,如果您真的希望收集器运行,则输入较低的数字(接近0.0),即使自上次收集以来没有太多活动(当前由分配的字节数测量),并且如果您只想在我们已经接近本来会发生回收的点时才暂停收集,则输入较大的数字(接近1.0)。
这里的动机是针对例如游戏中需要将GC发生的时间稍微偏移一点的情况,例如在游戏的关卡变化期间执行GC,而不是在玩家开始探索关卡两秒钟后执行GC。
一个非常重要的细节:这个新API支持Release和Debugger Flash Runtimes。这使它比调用System.gc()更加出色。
<mx:DataGrid id="mygrid" dataProvider="{DataCacher.instance().result('method').data}" ... />
当包含此数据表格的弹出窗口关闭时,您会期望绑定关系被销毁。显然,它们一直存在。嗯,Flex不应该在对象被标记为GC并删除最后一个引用时销毁所有绑定关系(即事件侦听器)吗?这对我来说可能是解决问题的方法。
至少我认为是这样,我还是Flex的初学者,欢迎提出任何想法。
正如其他人所说:不要尝试手动进行垃圾回收,虽然有一些技巧,但并不安全。
当可能时,您应该尝试对对象进行回收 - 这将节省大量内存。
例如,这可以应用于BitmapData(清除和重用),粒子(从显示列表中删除并重用)等。
try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*){
trace("Forcing Garbage Collection :"+e.toString());
}
回收并不能真正地帮助。我使用了一个加载器,每500毫秒重复加载同一张jpg图片。任务管理器仍然报告内存不断增加。
这里有经过尝试和证明的解决方案。
如果必要的话,调用垃圾回收器可能会很有用...所以,你必须小心地考虑何时以及如何进行操作,但毫无疑问,在某些情况下是必要的。
例如,如果您有一个模块化的应用程序,在从一个视图切换到另一个视图时,所有已删除的对象可能代表应尽快可用的大量内存,您只需要控制正在处理的变量和引用即可。
System.pauseForGCIfCollectionImminent()
的方法可供调用。它接受一个参数,以便您可以告诉GC收集需要多么迫在眉睫才能发生暂停。有关更多详细信息/链接,请参见下面我的答案。 - pnkfelix