【问题标题】:how to predict jvm garbage collection如何预测jvm垃圾回收
【发布时间】:2017-03-05 20:52:39
【问题描述】:

我正在开发一个用 java 编写的关键应用程序,它应该避免“停止世界垃圾收集”的影响。 我正在寻找一种可以预测由于完整 gc 导致的长时间停顿的解决方案。有可能吗?

【问题讨论】:

  • 如果有时 GC 是可接受的,您可以随时尝试调用 System.gc()。当这个调用返回时,新的 GC 不太可能在不久的将来发生。
  • 这个问题不是关于统计预测的,所以'prediction'标签可能放错了。
  • @Ole V.V. gc() 很容易不会发生或被禁用。 “不久的将来”是一个无定形的术语,新 GC 的可能性完全取决于 OP 系统的细节、它的运行时配置文件和它的错误,我们对此一无所知。所以我们还不能负责任地断言gc() 会产生的影响。
  • 对延迟敏感的应用程序的常用方法不是尝试预测暂停,而是测量并减少暂停。
  • @LewBloch 当然,可以禁用 GC,但是后来有人禁用了它。这在您自己的服务器上很容易避免。您可以对其进行测试,如果它有效,您可以依赖它。也就是说,变化在于有更好的解决方案。

标签: java performance garbage-collection prediction


【解决方案1】:

您能做的最好的事情是减少分配和/或使用像 Azul 那样的无暂停 GC。这将使 GC 更易于管理。

如果您在关键部分(使用指标识别,例如 JMC/JFR 之类的分析器)减少了足够多的分配,您可以运行一整天而没有完整的收集,或者在极端情况下,整天运行而没有次要收集。

您可以监控tenured空间的使用情况并查看它是否已被填满(full GC还有其他原因,但这是最常见的)

【讨论】:

  • “减少分配”可能会显着降低 GC 性能,因为人们为减少分配所做的大多数事情都会导致对象一直存在,直到它们被提升为“终身”。这不是天真地遵循的建议。更好的建议是在算法允许的最窄范围内分配引用,以便年轻代 GC 成为规则,并尽可能早地释放对象以避免内存泄漏(打包)。此外,将对象设计为需要最少的初始化。遵循最佳固有程序逻辑以获得最佳 GC 配置文件。
  • @LewBloch 分配对象涉及通常应该避免的工作。理想情况下,逃逸分析可以消除分配,因此我会避免优化 jit 可以为您优化的代码,即仅在运行时删除实际分配,而不是您认为发生分配的位置。您确实希望避免对象在永久空间中死亡,尽管我很少看到这种情况,特别是如果您可以拥有很少的次要集合。
  • 分配对象几乎不需要时间,可能需要十或十二个机器指令。内存系统保证 JVM 只需要存储一个指针并提升堆顶标记。需要时间的是初始化。我的建议考虑了这一点,并且像你的一样,提倡避免让对象到达终身代。大多数对象都应该在年轻时死去。
  • @LewBloch 分配造成的内存压力降低了缓存效率并减慢了每次内存访问,您只需减少关键部分的分配即可将应用程序的性能提高 2-5 倍。
  • @LewBloch 我同意以不集中的方式更改代码在性能方面可能会造成同样的伤害,但增加复杂性使维护更加困难。只有优化由指标驱动的代码才有意义,例如像 jfr 这样的分析器。
【解决方案2】:

这根本不可能。我认为避免“停止世界”垃圾收集的最佳方法是最小化对象的寿命。小跑。

顺便说一句,您需要尝试不同的解决方案并对其进行分析。

【讨论】:

  • 很好的建议,并允许年轻代 GC 占据主导地位,其中分配几乎免费,释放完全免费,并确保活动对象副本尽可能小。
【解决方案3】:

为什么不强制定期 GC,例如频率取决于内存使用情况?

【讨论】:

  • 因为你不能?
猜你喜欢
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
  • 2011-02-23
  • 1970-01-01
  • 2018-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多