0%

大堆问题定位

03.大堆问题定位

  1. 首先确定是内存问题,还是内存泄露。如果是内存问题,则可以通过JVM监控等手段,判断内存持续增长的区域;假设确定了是内存泄露,也可能是堆内或者堆外
  2. 堆内内存泄露的情况,最有效的手段莫过于Heap Dump,使用jmap -heap $PIDjcmd或者HeapDumpOnOutOfMemoryError等等手段都可以获取,使用MAT找超级powerful的机器分析;MAT 其实提供了分析脚本可以在不用 IDE 加载整个 HEAP 获取到需要的信息, 也就是通过脚本解析 HEAP 逐步分析, 具体可参考 How to Analyse Large Heap Dumps. PS: 曾经分析过 108G 的堆
  3. 实际生产中,这么大的堆,不管是dump对生产系统的影响,还是dump本身的难度,都往往不切实际,相对低成本的手段:
  4. jmap -histo $PIDjmap -histo:live $PID获得当前堆内对象的个数统计,并采样多次,查看一下里面object的分布,看哪类对象比较多,一般来说200G的堆,做一次jmap -histo可能要几十秒到一分钟,可能会触发full gc,如果使用 CMSG1 的话, 可加入 -XX:+ExplicitGCInvokesConcurrent 使用并发收集器显式;如果不能探明的话, 只能使用 jmap 将整个堆 dump 下来。
    所以如果有类似timeout killer的守护线程,要注意不要让它把进程kill掉
  5. 详细的GC日志等,比如判断引用堆积情况等,看看没有没什么异常, 比如有没有因为metaspace 满了而导致的GC。这种情况,可以看看是不是打开XX:+TraceClassLoading -XX:+TraceClassUnloading 分析下类加载情况。
  6. 使用Tencent JDK,可以利用old object sampling技术,不做Heap dump定位相当一部分memory leak
  7. 堆外内存: 确认下是否是 Java 的 direct bytebuffer 泄露, 由于采用 reference 机制回收, 如果一直没有触发 JVM GC 或回收线程偏少也会导致堆外内存回收缓慢导致泄露
    如果是 Native 或者使用 Unsafe 方式直接向 OS 申请内存, 可通过 NMT以及 pmap 等查看, JDK 团队分享的 http://km.oa.com/group/42239/articles/show/404478?ts=1574932416 可谓是面面俱到.

使用MAT命令行分析

How to Analyse Large Heap Dumps

  1. 下载MAT

  2. 到MAT的安装目录下,打开MemoryAnalyzer.ini,调整MAT的启动jvm参数

    1
    2
    3
    4
    5
    6
    7
    -Xms6144m
    -Xmx8192m
    -XX:+UseConcMarkSweepGC
    -XX:+UseParNewGC
    -XX:+CMSParallelRemarkEnabled
    -XX:+CMSClassUnloadingEnabled
    -XX:+UseCMSInitiatingOccupancyOnly

    堆最大大小调整为机器内存大小

  3. dump文件所在文件夹,确保有dump文件两倍的空间

  4. 到MAT的安装目录下,使用root账户运行命令
    For UNIX:

    1
    2
    3
    ./ParseHeapDump.sh /opt/heap_dump/jvm.hprof org.eclipse.mat.api:suspects
    ./ParseHeapDump.sh /opt/heap_dump/jvm.hprof org.eclipse.mat.api:overview
    ./ParseHeapDump.sh /opt/heap_dump/jvm.hprof org.eclipse.mat.api:top_components

    For Windows:

    1
    2
    3
    ParseHeapDump.bat D:\heap_dump\jvm.hprof org.eclipse.mat.api:suspects
    ParseHeapDump.bat D:\heap_dump\jvm.hprof org.eclipse.mat.api:overview
    ParseHeapDump.bat D:\heap_dump\jvm.hprof org.eclipse.mat.api:top_components
  5. 使用MAT打开生成的分析结果文件