Java堆过大导致的OOM问题排查和MAT的使用

获取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是需要考虑的。

参数优点缺点
HeapDumpOnOutOfMemoryErrorOOM时生成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.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值