如果您像我一样对Java性能充满热情,那么堆转储分析对您来说应该不是一个谜。 如果是这样,那么好消息是您将有机会提高您的Java故障诊断技能和JVM知识。
JVM现已发展到今天,与旧的JDK 1.0 – JDK 1.4天相比,今天生成和分析JVM堆转储要容易得多。
堆转储分析不应视为替代配置文件和JVM分析工具(例如JProfiler或Plumbr),而是可以互补的。 在对Java堆内存泄漏和java.lang.OutOfMemoryError问题进行故障排除时,此功能特别有用。
这篇文章将为您提供JVM堆转储的概述以及对它的期望。 它还将提供有关如何以及何时应该花时间分析堆转储的建议。 未来的文章将包括有关分析过程本身的教程。
Java堆转储概述
JVM堆转储基本上是给定时间的Java堆内存的“快照”。 它与作为线程快照的JVM线程转储完全不同。
此类快照包含有关Java对象和在Java堆上分配的类的低级详细信息,例如:
- Java对象,例如Class,字段,原始值和引用
- 与类加载器相关的数据,包括静态字段(对于类加载器泄漏问题很重要)
- 可从堆外部访问的垃圾收集根或对象(系统类加载器已加载资源,例如rt.jar,JNI或本机变量,线程,Java Locals等)
- 与线程相关的数据和堆栈(对于突然出现的Java堆增加问题特别有用,尤其是与线程转储分析结合使用时)
请注意,通常建议在完整GC之后生成堆转储,以消除未引用对象中不必要的“噪音”。
分析保留给精英?
在过去的十年中,与生产支持团队一起工作时,我发现一个普遍的误解是给人留下深刻印象,即更深入的分析任务(例如性能分析,堆转储或线程转储分析)留给了“精英”或产品供应商(Oracle,IBM等)。 。
我完全不同意。
作为Java开发人员,您编写的代码可能在高度并发的线程环境中运行,从而在JVM上管理数百个对象。 您不仅要担心并发问题,还要担心垃圾回收和应用程序的内存占用。 由于您是应用程序的专家,因此您处于执行此分析的最佳位置。
在下面找到您应该能够回答的典型问题:
- 根据负载预测,需要多少个并发线程来并发运行我的应用程序? 每个活动线程在完成任务之前要消耗多少内存?
- 我的应用程序的静态内存占用量是多少? (库,类加载器占用空间,内存中缓存数据结构等)
- 负载下我的应用程序的动态内存占用量是多少? (会话足迹等)
- 您是否对应用程序进行了概要分析,以防内存泄漏?
负载测试,对应用程序进行性能分析以及分析Java堆转储(例如:在负载测试或生产问题期间捕获)将使您能够回答上述问题。 然后,您将可以实现以下目标:
- 降低生产实施后出现性能问题的风险
- 通过为生产和产能管理团队提供额外的指导和事实,为您的工作和客户增加价值; 允许他们采取适当的IT改进措施
- 分析影响客户IT生产环境的内存泄漏或占用空间问题的根本原因
- 通过学习这些性能分析原理和技术来提高您的技术技能
- 通过提高您对JVM,垃圾回收和Java对象生命周期的了解来提高JVM技能
您想要了解的最后一件事是技能“高原”。 如果您不喜欢这种类型的分析,那么我的建议如下:
- 要求团队中更高级的成员执行堆转储分析并确定他的工作和方法
- 一旦您感到更自在,就请自己自愿执行相同的分析(针对不同的问题案例),这一次请一位经验丰富的成员来完成您的分析工作
- 最终,学生(您)将成为导师
何时使用
每次遇到Java堆问题(例如OutOfMemoryError)时,都不应分析JVM堆转储。 由于这可能是一个耗时的分析过程,因此我建议针对以下情况进行此分析:
- 需要了解和调整您的应用程序和/或周围的API或Java EE容器本身的内存占用量
- Java堆内存泄漏故障排除
- Java类加载器内存泄漏
- 突然的Java堆增加问题或触发事件(必须与线程转储分析结合起来作为起点)
现在,在下面找到与堆转储分析相关的一些限制:
- JVM堆转储生成是一项繁重的计算任务,它将使您的JVM挂起直到完成。 需要进行适当的尽职调查,以减少对生产环境的影响
- 分析堆转储不会提供完整的Java进程内存占用量,例如本机堆。 为此,您将需要依赖其他工具和OS命令
- 您可能会遇到打开和解析从旧版本的JDK(例如1.4或1.5)生成的堆转储时遇到的问题
堆转储生成技术
JVM堆转储通常是通过以下2个操作生成的:
- 由于java.lang.OutOfMemoryError(例如Java Heap,PermGen或本机堆耗尽)而自动生成或触发
- 通过使用诸如jmap,VisualVM(通过JMX)或OS级命令之类的工具手动生成
#自动触发的堆转储
如果您使用的是HotSpot Java VM 1.5+或JRockit R28 +,则需要在JVM启动时在下面添加以下参数:
-XX:+HeapDumpOnOutOfMemoryError
上面的参数将使HotSpot VM在OOM事件之后自动生成堆转储。 这些JVM类型的堆转储格式为HPROF(* .hprof)。
如果您使用的是IBM JVM 1.4.2+,那么默认情况下会启用OOM事件导致的堆转储。 IBM JVM的堆转储格式为PHD(* .phd)。
#手动触发的堆转储
可以按以下方式手动生成JVM堆转储:
- jmap在HotSpot 1.5+中的使用
- VisualVM for HotSpot 1.6+的使用*推荐*
**请对您的生产环境进行适当的尽职调查,因为JVM堆转储生成是一个侵入性过程,它将使您的JVM进程挂起直到完成**
如果使用的是IBM JVM 1.4.2,则需要从JVM启动中添加以下环境变量:
export IBM_HEAPDUMP=true
export IBM_HEAP_DUMP=true
对于IBM JVM 1.5+,您将需要在Java启动时添加以下参数:
-Xdump:heap
例如:
java -Xdump:none -Xdump:heap:events=vmstop,opts=PHD+CLASSIC
JVMDUMP006I Processing Dump Event 'vmstop', detail '#00000000' - Please Wait.
JVMDUMP007I JVM Requesting Heap Dump using
'C:\sdk\jre\bin\heapdump.20050323.142011.3272.phd'
JVMDUMP010I Heap Dump written to
C:\sdk\jre\bin\heapdump.20050323.142011.3272.phd
JVMDUMP007I JVM Requesting Heap Dump using
'C:\sdk\jre\bin\heapdump.20050323.142011.3272.txt'
JVMDUMP010I Heap Dump written to
C:\sdk\jre\bin\heapdump.20050323.142011.3272.txt
JVMDUMP013I Processed Dump Event 'vmstop', detail '#00000000'.
请查看IBM JVM1.5 +的Xdump文档。
对于Linux和AIX®,通过kill –QUIT或kill -3发送IBM JVM堆转储信号。 此OS命令将触发JVM堆转储生成(PHD格式)。
我建议您查看MAT摘要页面,以了解如何通过各种JVM和OS组合获取JVM堆转储。
堆转储分析工具
我推荐的用于打开和分析JVM堆转储的主要工具是Eclipse Memory Analyzer (MAT)。 到目前为止,这是SAP和IBM等贡献者中最好的工具。 该工具提供了丰富的界面和先进的堆转储分析功能,其中包括“泄漏可疑”报告。 MAT还支持HPROF和PHD堆转储格式。
我建议在较早的文章中获得有关如何使用MAT和分析您的第一个JVM堆转储的快速教程 。 我也有一些堆转储分析案例研究对您的学习过程很有用。
最后的话
我真的希望您能像我一样喜欢JVM堆转储分析。 以后的文章将为您提供有关如何分析JVM堆转储以及从何处开始的通用教程。 请随时提供您的意见。
参考: Java堆转储:您可以完成任务吗? 从我们的JCG合作伙伴 Pierre-Hugues Charbonneau在Java EE支持模式和Java教程博客中获得。
翻译自: https://www.javacodegeeks.com/2012/11/java-heap-dump-are-you-up-to-the-task.html