获取Heap Profile文件
线上服务出现问题,第一步做的一定是及时止损,然后再找原因和修复。
对于Java服务,如果启动参数配置了
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/woods -Dfile.encoding=UTF-8
那么在服务OOM时直接就可以在相应路径下就可以拿到heap dump的heap profile文件了。但是,如果启动服务时没有指定以上参数,例如只是指定了
-XX:+ExitOnOutOfMemoryError
,这时在OOM时就拿不到hprof了,此时可以手动执行
jmap -dump:format=b,file=<test.hprof> <pid>
,从而拿到堆文件。
注意这里大多数情况下都是不需要在dump的参数中指定live的,即
jmap -dump:live,format=b,file=<test.hprof> <pid>
,因为指定live会触发一次Full GC,这样一些不可达的对象直接被回收了。不指定live参数,默认是将堆中所有对象dump出来。
当然,在服务中选择-XX:+HeapDumpOnOutOfMemoryError还是-XX:+ExitOnOutOfMemoryError是需要考虑的。
参数 | 优点 | 缺点 |
---|---|---|
HeapDumpOnOutOfMemoryError | OOM时生成hprof文件,便于后续问题分析 | 如果堆特别大,那么heap dump会占用较长时间,可能导致服务不可用 |
ExitOnOutOfMemoryError | 通常服务部署在容器里,如果服务是1号进程,那么jvm在发现oom时直接退出,容器立刻处于Terminating状态, 并且变为Terminated | 获取不到OOM时堆的信息 |
一些概念
HeapDump
Heap Dump是Java进程在某个时间点的内存快照。
HeapDump中不包含分配信息,因此通过HeapDump不能知道对象是谁以及在哪创建的。
Memory Analyzer工具支持HPROF binary heap dumps、 IBM system dumps以及IBM portable heap dumps。
Heap Dump中通常包含以下信息:
-
All Objects
Class, fields, primitive values and references -
All Classes
Classloader, name, super class, static fields -
Garbage Collection Roots
Objects defined to be reachable by the JVM -
Thread Stacks and Local Variables
The call-stacks of threads at the moment of the snapshot, and per-frame information about local objects
Reachability
Java对象有对其他对象的引用,例如field references (for simple objects),array elements (for object arrays)或者various hidden references(例如每个对象包含对它的类型的引用、每个class包含对加载它的class loader的引用)。
Reachable
这些对象和引用构成了一个有向无环图,图中的顶点是对象,图中的有向边是对象的引用关系。Garbage Collection Roots是这个有向图的根。
对于对象A,如果图中有一条路径可以从对象A到达对象B,那么称对象B从对象A是可达的。
Unreachable Object
如果从GC Root到某个对象没有路径,那么这个对象就是不可达的。一个合法的Java程序是访问不到这些不可达对象的,因此这些对象是可以被垃圾回收的。
Shallow Heap和Retained Heap
Shallow Heap 是一个对象占用的内存。例如对于64位的JVM,如果开启类指针压缩(默认开启,-XX:+UseCompressedClassPointers
),一个类指针占用4Byte,每个int占用4Byte,每个long占用8Byte等等。
Retained Set of X,当对象X被垃圾回收时,顺带被回收的对象集合。
Retained heap of X,当X被回收时,可以释放的内存空间,也就是对象X和它支配的对象的大小总和。
Dominator Tree
MAT工具进行深度优先遍历,将对象构成有向图,然后将有向图转化成一个支配树(Dominator Tree),转化规则是“如果有且只有A这一条路能够走到B,那么A称为B的支配者。离B最近的支配者称为B的直接支配者”,在支配树中,每个节点是它的孩子的直接支配者。
Garbage Collection Roots
可以从堆外直接访问的对象是GC Root,满足以下的条件可以称为GC Root。
- System Class
Class loaded by bootstrap/system class loader. For example, everything from the rt.jar like java.util.* . - JNI Local
Local variable in native code, such as user defined JNI code or JVM internal code. - JNI Global
Global variable in native code, such as user defined JNI code or JVM internal code. - Thread Block
Object referred to from a currently active thread block. - Thread
A started, but not stopped, thread. - Busy Monitor
Everything that has called wait() or notify() or that is synchronized. For example, by calling synchronized(Object) or by entering a synchronized method. Static method means class, non-static method means object. - Java Local
Local variable. For example, input parameters or locally created objects of methods that are still in the stack of a thread. - Native Stack
In or out parameters in native code, such as user defined JNI code or JVM internal code. This is often the case as many methods have native parts and the objects handled as method parameters become GC roots. For example, parameters used for file/network I/O methods or reflection. - Finalizable
An object which is in a queue awaiting its finalizer to be run. - Unfinalized
An object which has a finalize method, but has not been finalized and is not yet on the finalizer queue. - Unreachable
An object which is unreachable from any other root, but has been marked as a root by MAT to retain objects which otherwise would not be included in the analysis. - Java Stack Frame
A Java stack frame, holding local variables. Only generated when the dump is parsed with the preference set to treat Java stack frames as objects. - Unknown
An object of unknown root type. Some dumps, such as IBM Portable Heap Dump files, do not have root information. For these dumps the MAT parser marks objects which are have no inbound references or are unreachable from any other root as roots of this type. This ensures that MAT retains all the objects in the dump.