对于一款游戏(使用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运行。有两种可能的方法可以帮助消除滞后:
- 确保在动画完成之前,一直抓住动画过程中创建的所有对象。然而,这可能会导致严重的内存问题,这一切都取决于对象的数量及其内存消耗
- 在动画期间定期运行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合作时,请记住这一点。