【问题标题】:adobe AIR: prevent GC from runningadobe AIR:阻止 GC 运行
【发布时间】:2012-02-25 03:16:14
【问题描述】:

对于游戏(使用 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,但会导致大约一秒的延迟。在这 30 秒的序列中,GC 会触发两次。

所以我的问题是关于防止 GC 在这 30 秒内触发的任何技术、黑客或解决方法(除了一般优化内存使用 - 显然我已经在努力)?

谢谢。

【问题讨论】:

  • 你有很多对象吗?
  • 嗯 - 很多 - 我会说几百个 - 但我不会在这个序列中创建大量新的(我可能会添加 50 个显示对象并在这 30 秒内再次删除它们)
  • 在序列之前创建对象是否会有所帮助,保持它们不可见并只是玩可见性而不用对象创建/删除来警告 GC...

标签: actionscript-3 air garbage-collection


【解决方案1】:

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

首先,您应该检查它是否已启用。 documentation 说:

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

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

【讨论】:

  • 我知道调试和安装的应用程序 - 但我认为 AIR for iOS 是安装的应用程序?
【解决方案2】:

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

垃圾收集运行是因为系统需要更多资源,如果系统耗尽资源,您的应用将崩溃。或许您应该考虑另一种方式来执行您的任务,这种方式对资源的消耗较少。

另外请注意,在您的代码中使用 System.gc() 仅适用于 Flash Player 的调试版本。

我想我还在某处读到,要正确使用 System.gc() 作为测试的一部分,您应该调用它两次:

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

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

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

【讨论】:

  • 它似乎并不需要内存。我减少了内存占用,并且滞后仍然发生在完全相同的时间。发生这种情况时,System.privateMemory 的内存使用量会短暂下降(此时 System.totalMemory 和 System.freeMemory 似乎没有受到影响)。会不会是与我的 ByteCode 无关但与 AIR 运行时本身的垃圾收集有关的垃圾收集?
  • 不确定。我想知道使用怪物调试器是否可以对正在发生的事情有所了解。 demonsterdebugger.com
【解决方案3】:

正如其他人所说,无法阻止 GC 运行。有 2 种可能的方法可能有助于消除滞后:

  1. 确保在动画结束之前保留在动画期间创建的所有对象。然而,这可能会导致严重的内存问题,这完全取决于对象的数量及其内存消耗
  2. 在动画期间定期运行 System.gc()(两次),这将导致内存清理被分配,并有望分散延迟

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      您可以通过不创建垃圾来防止这种情况。这意味着,没有未引用的对象、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 时请记住这一点。

      【讨论】:

        猜你喜欢
        • 2011-05-09
        • 1970-01-01
        • 2010-10-14
        • 2012-05-26
        • 1970-01-01
        • 2013-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多