是否有针对 GC 问题的食谱指南?

2022-09-01 06:59:07

几乎每个人最终都会遇到Java的GC问题。

是否有说明书指南或半自动化工具来调整 Java 的 GC?

我的理由是这样的:

  • 几乎任何人最终都会有这些问题
  • 有许多可能的因素(例如20个),其中只有少数影响您的问题。
  • 大多数人不知道如何识别关键因素,因此GC调音更像是一门黑色艺术,而不是一门科学。
  • 并非每个人都使用 HotSpot VM。不同的 Sun 版本具有不同的 GC 特性。
  • 几乎没有动力进行试验(例如每天使用略有不同的设置运行 VM,以查看它们如何发挥作用)。

所以问题真的是:有没有我可以以清单方式使用的东西?或者甚至是一个分析GC日志或堆转储的工具,并给我特定的提示在哪里查找(而不是告诉我“95%的数据分配在byte[]类型的对象中”,这基本上是无用的)。

相关问题:


答案 1

在各种资源中,我编制了一个健全性清单,用于分析应用程序的GC行为和性能。这些准则是通用的,适用于任何特定于供应商的 JVM,但也包含特定于 HotspotVM 的信息以进行说明。

  1. 禁用显式 GC。显式GC是一种糟糕的编码实践,它永远不会有帮助。用。-XX:+DisableExplicitGC

  2. 启用完整 GC 日志记录。轻巧而强大。

    • 计算实时数据集分配率促销率。这将告诉您是否需要更大的堆,或者您的例如。年轻的一代太小了,或者如果你的幸存者空间溢出,等等。
    • 计算总GC时间,它应该是总运行时间的<5%。
    • -XX:+PrintTenuringDistribution -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log -XX:+HeapDumpOnOutOfMemoryError -Xloggc:gc.log -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -showversion
  3. 考虑收集有关您的 GC 信息的其他方法。日志记录很好,但有时有可用的轻量级命令行工具可以为您提供更多的见解。例如。 对于热点,它将显示伊甸园,幸存者和旧将军的职业/容量。jstat

  4. 收集类直方图这些是轻量级的,将显示堆的内容。您可以在发现一些奇怪的GC活动时拍摄快照,也可以在Full GC之前/之后拍摄快照:

    • OldGen 空间的内容:您可以找出哪些对象驻留在 OldGen 中。您需要在完整 GC 之前和之后打印直方图。由于 YoungGen 集合是在完整 GC 之前执行的,因此这些直方图将显示旧一代的内容。用-XX:+PrintClassHistogramBeforeFullGC -XX:+PrintClassHistogramAfterFullGC.
    • 检测过早升级的对象:要确定是否有任何实例被提前升级,您需要研究直方图以查看哪些类应驻留在 OldGen 中,以及哪些类应仅在 YoungGen 中看到。这不能自动完成,您需要推理每个类及其实例的用途,以确定该对象是否是临时的。
  5. 考虑不同的 GC 算法。VM 通常带有几种不同的 GC 实现,这些实现提供了各种权衡:吞吐量、占用空间、无暂停/短暂停、实时等。考虑您拥有的选项,然后选择适合您需求的选项。

  6. 谨防 finalize() 。使用 检查 GC 是否跟上了类的进度。此方法的执行成本可能非常高,这可能会影响 GC 和应用程序吞吐量。finalize()

  7. 堆转储。这是重量级的第一步,将影响正在运行的应用程序。收集堆转储以进一步研究堆内容或确认在步骤 4 中观察到的假设。

使用的资源:

书:

演讲/文章:

邮件列表:


答案 2

各种 GC 信息的参考:

神谕

使用 5.0 Java[tm] 虚拟机调整垃圾回收

这个也

Java SE 6 HotSpot[tm] 虚拟机垃圾回收调优

国际商业机器

微调垃圾回收 [链接已死]

可扩展的详细工具包

SAP JVM

内存管理(垃圾回收)

检测内存泄漏

检测挂起/循环的虚拟机

分析内存不足的情况

很抱歉,我对SAP了解不多,但提供了一些我发现的东西。

至于说明书,调优很可能是此级别特定于应用程序的,但这是一个有趣的主题。

补遗

您还提到了分析工具。下面列出了一些候选者:

知道任何Java垃圾回收日志分析工具吗?