adobeAIR:阻止GC运行



对于一款游戏(使用iOS版AIR),我想阻止GC在特定的30秒序列中运行(因为它会导致非常显著的滞后)。

我已经在序列开始之前调用System.gc()了。在这个序列中,我没有创建很多新对象,只有一些动画播放和对象移动(在3D中)。一些物体移出舞台。

该序列中的内存统计信息近似为:

System.totalMemory: 4.5 MB
System.freeMemory: 1.0 MB
System.privateMemory: 75 MB

GC启动时,System.privateMemory会降至74MB,但会导致大约1秒的延迟。GC在这30秒的序列中发射两次。

所以我的问题是关于任何技术、技巧或解决方法(除了优化内存使用之外——显然我已经在做了)来防止GC在这30秒内启动?

谢谢。

您无法阻止GC运行。但我想指出,调用System.gc()有两个问题。

首先,您应该检查它是否已启用。文件上写着:

仅适用于Flash Player调试器版本和AIR应用程序。在AIR应用程序中,System.gc()方法仅在AIR调试启动器(ADL)中运行的内容中启用,或者在已安装的应用程序中在应用程序安全沙盒中的内容中禁用。

其次,只调用System.gc()一次,实际上可能不会释放内存。请参阅此处了解更多信息。

我不确定是否可以阻止垃圾收集运行。

运行垃圾回收是因为系统需要更多的资源,如果系统资源不足,您的应用程序将崩溃。也许你应该想出另一种方法来完成你的任务,减少资源的匮乏。

还要注意,在代码中使用System.gc()只能在Flash Player的调试版本中工作。

我想我在某个地方也读到过,要正确地使用System.gc()作为测试的一部分,你应该调用它两次:

 System.gc();
 System.gc();

第一次标记未使用的内存,第二次sweep

http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html

正如其他人所说,不可能阻止GC运行。有两种可能的方法可以帮助消除滞后:

  1. 确保在动画完成之前,一直抓住动画过程中创建的所有对象。然而,这可能会导致严重的内存问题,这一切都取决于对象的数量及其内存消耗
  2. 在动画期间定期运行System.gc()(两次),这将导致内存清理的分布,并有望分散滞后

您可以在序列开始前尝试调用system.useForGCIfCollectionImminent()

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/System.html#pauseForGCIfCollectionImminent()具有高的紧迫性值(1)?

您可以通过不创建垃圾来防止这种情况。这意味着没有未引用的对象、null对象等。当您知道性能并不重要时,您可以通过删除所有引用并将其设为null来销毁对象,GC将开始执行它的工作。

GC仍将"寻找垃圾",但它应该使用更少的意外资源。

引用的问题是,AS3中的所有对象都是指向"真实"对象的指针,除了int、uint、String等基元值。这很容易验证

var a = new Object(); // we create an Object and a pointer called "a"
a.property = "I'm alive";
var b = a; // we create a pointer to the Object called "b"
a = null; // the Object still exists
trace(b.property) // I'm alive
b = null; // the Object still exists but is unreferenced, and will be GCed
trace(b.property) // Error

在与GC合作时,请记住这一点。