在各种资源中,我编制了一个健全性清单,用于分析应用程序的GC行为和性能。这些准则是通用的,适用于任何特定于供应商的 JVM,但也包含特定于 HotspotVM 的信息以进行说明。
禁用显式 GC。显式GC是一种糟糕的编码实践,它永远不会有帮助。用。-XX:+DisableExplicitGC
-
启用完整 GC 日志记录。轻巧而强大。
- 计算实时数据集、分配率和促销率。这将告诉您是否需要更大的堆,或者您的例如。年轻的一代太小了,或者如果你的幸存者空间溢出,等等。
- 计算总GC时间,它应该是总运行时间的<5%。
- 用
-XX:+PrintTenuringDistribution -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log -XX:+HeapDumpOnOutOfMemoryError -Xloggc:gc.log -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -showversion
考虑收集有关您的 GC 信息的其他方法。日志记录很好,但有时有可用的轻量级命令行工具可以为您提供更多的见解。例如。 对于热点,它将显示伊甸园,幸存者和旧将军的职业/容量。jstat
-
收集类直方图这些是轻量级的,将显示堆的内容。您可以在发现一些奇怪的GC活动时拍摄快照,也可以在Full GC之前/之后拍摄快照:
-
OldGen 空间的内容:您可以找出哪些对象驻留在 OldGen 中。您需要在完整 GC 之前和之后打印直方图。由于 YoungGen 集合是在完整 GC 之前执行的,因此这些直方图将显示旧一代的内容。用
-XX:+PrintClassHistogramBeforeFullGC -XX:+PrintClassHistogramAfterFullGC.
-
检测过早升级的对象:要确定是否有任何实例被提前升级,您需要研究直方图以查看哪些类应驻留在 OldGen 中,以及哪些类应仅在 YoungGen 中看到。这不能自动完成,您需要推理每个类及其实例的用途,以确定该对象是否是临时的。
考虑不同的 GC 算法。VM 通常带有几种不同的 GC 实现,这些实现提供了各种权衡:吞吐量、占用空间、无暂停/短暂停、实时等。考虑您拥有的选项,然后选择适合您需求的选项。
谨防 finalize() 。使用 检查 GC 是否跟上了类的进度。此方法的执行成本可能非常高,这可能会影响 GC 和应用程序吞吐量。finalize()
堆转储。这是重量级的第一步,将影响正在运行的应用程序。收集堆转储以进一步研究堆内容或确认在步骤 4 中观察到的假设。
使用的资源:
书:
演讲/文章:
邮件列表: