对于游戏(使用AIR for iOS),我想阻止GC在特定的30秒序列中运行(因为它会导致非常明显的滞后)。
我已经做的是在序列开始之前调用System.gc()。在序列中,我不创建许多新对象,只有一些动画播放和对象移动(在3D中)。一些物体移出舞台。
此序列中的内存统计信息是近似的:
System.totalMemory: 4.5 MB
System.freeMemory: 1.0 MB
System.privateMemory: 75 MB
当GC触发时,System.privateMemory降至74 MB,但会导致大约一秒钟的滞后。 GC在此30秒序列中发射两次。
所以我的问题是关于任何技术,黑客或工作场所(除了优化内存使用情况 - 显然我已经在努力)以防止GC在这30秒内被解雇?
感谢。
答案 0 :(得分:2)
您无法阻止GC运行。但我想指出,调用System.gc()
有两个问题。
首先,您应该检查它是否已启用。 documentation说:
仅适用于Flash Player调试器版本和AIR应用程序。在AIR应用程序中,System.gc()方法仅在AIR Debug Launcher(ADL)中运行的内容中启用,或者在已安装的应用程序中,在应用程序安全沙箱中的内容中启用。
其次,只调用一次System.gc()
,实际上可能无法释放内存。请点击此处查看更多information。
答案 1 :(得分:1)
我不确定你是否可以防止垃圾收集运行。
垃圾收集运行是因为系统需要更多资源,如果系统资源不足,您的应用程序将崩溃。也许您应该想到另一种方法来执行资源不足的任务。
另请注意,在代码中使用System.gc()只能在Flash Player的调试版本中使用。
我想我也在某处读到要正确使用System.gc()作为测试的一部分,你应该调用它两次:
System.gc();
System.gc();
第一次标记未使用的内存,第二次扫描。
http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html
答案 2 :(得分:1)
正如其他人所说,不可能阻止GC运行。有两种可能的方法可以帮助摆脱滞后:
答案 3 :(得分:1)
您可以在序列开始前尝试调用system.useForGCIfCollectionImminent()
。
答案 4 :(得分:0)
您可以通过不创建垃圾来防止这种情况。这意味着,没有未引用的对象,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时请记住这一点。