【问题标题】:Waiting for GC to finish before starting game with Java?在使用 Java 开始游戏之前等待 GC 完成?
【发布时间】:2012-01-06 00:05:15
【问题描述】:

我正在制作一个快节奏的实时 Android 游戏,一切运行良好,但游戏开始的前几秒非常滞后,因为加载后垃圾收集器正在清理线。当然,玩家可以等待几秒钟(比如 10 多秒),因为完成后它开始运行非常流畅,但这看起来真的很难看,感觉游戏有问题。

有没有办法(或技术)来判断何时可以安全地开始游戏,这样垃圾收集器就不会在实时部分开始时就开始发疯?在不破坏事物的情况下,大脂肪加载线程不能减少太多。

【问题讨论】:

  • "非常缓慢,因为垃圾收集器在加载线程之后进行清理。" - 这是否表明您在加载期间正在搅动内存,或者只是加载时间?如果是前者,那你可以避免吗?
  • @Mitch:这表明加载器使用了很多对象(或一些大型对象)。在初始化完成之前,它们可能都不符合收集条件。
  • @cHao:我很好奇为什么加载器需要很多对象?
  • @Mitch:因为它正在设置所有内容并让应用程序准备好运行?可能有各种各样的配置加载、资源查找、XML 解析等等等等……一旦一切都配置和加载并准备好,大部分东西都可以扔掉。但在此之前,加载程序仍然可以引用大量的东西。
  • @CHao:我认为这更有可能是 JIT 而不是加载本身。 (正如斯蒂芬 C 提到的)

标签: java android performance garbage-collection


【解决方案1】:

这似乎是System.gc() 可能有所帮助的情况。它告诉系统这将是收集垃圾的好时机。根据文档,

当控制从方法调用返回时,Java 虚拟机已尽最大努力从所有丢弃的对象中回收空间。

不过,文档还说,该方法“建议”收集对象——也就是说,不能保证它会有所帮助,特别是如果你仍然有一些引用被隐藏起来。如果它确实有效,它只会从正在运行的代码(包括运行时)中收集根本无法访问的对象。 (例如,该加载器线程在完成运行之前不符合收集条件并且您的代码不再引用它。)

【讨论】:

    【解决方案2】:

    您可以在开始游戏之前运行System.gc() 以手动强制垃圾收集器运行(并且,至少根据官方JavaDoc here,在从该方法调用返回之前完成)。但是,GC 通常是不确定的,无法保证它不会再次运行,或者就此而言,对 System.gc() 的调用将执行任何操作。

    【讨论】:

    • 是的,但this question 似乎表明 System.gc() 确实在 android 上做了一些事情,我认为这是运行 GC 的一个非常合法的案例。肯定不会疼的。
    【解决方案3】:

    如果您对此进行更深入的研究,您可能会发现大部分(甚至大部分)“滞后”并不是 GC 的错。我怀疑这主要是由于 JIT 编译。调用 System.gc() 可以改善事情,但我怀疑它会完全摆脱滞后。

    【讨论】:

    • 我认为这不是问题,因为当滞后发生时,我的日志会显示一堆行,上面写着“GC_CONCURRENT ...blah blah blah ...”,并且在lagg 消失:\ 编辑:另外,我只是在游戏开始后才开始注意到 lagg 变得越来越复杂,我不得不在加载功能中添加越来越多的内容。一开始并没有落后这么多
    猜你喜欢
    • 2014-03-30
    • 2020-03-04
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 2020-01-31
    • 2012-01-17
    • 2010-11-28
    • 2016-01-20
    相关资源
    最近更新 更多