美文网首页硬核技术
Java 内存 / cpu 问题排查方法

Java 内存 / cpu 问题排查方法

作者: 一字马胡 | 来源:发表于2020-02-26 10:20 被阅读0次

CPU问题

top

使用top查找出目前JVM中占有CPU最多的线程信息:


top -H -p <pid>
printf "%x\n" tid
jstack <pid> | grep "nid"

这种方法需要一些操作,如果使用Java-debug-tool,则仅需要一个命令即可获取到top N busy的线程信息,还可以获取特定状态的线程信息;

内存问题

CPU问题是比较容易排查出来的,但是内存问题就比较麻烦了,内存问题大致分为堆内存问题,以及堆外内存问题,可以根据特定的问题进行特定的分析。

OutOfMemoryError

拿到heap dump

  • 在JVM启动参数中增加参数:-XX:+HeapDumpOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=logs/heapdump.hprof
  • 运行时可以通过命令:jmap -dump:live,format=b,file=<path> <pid>

OutOfMemoryError 原因

  • java.lang.OutOfMemoryError: PermGen space / Metaspace

遇到这个oom,则首先应该想到是否加载的类太多了;

  • java.lang.OutOfMemoryError: Java Heap Space

遇到这个oom,则代表jvm无法在堆中找到一块内存来创建新的对象,所以是否创建了太多的对象,特别是大对象,如果是设置的堆太小,可以通过
-Xms / -Xmx 来设置一个大一些的数值;

  • OutOfMemoryError: unable to create new native thread

创建了太多的线程,所以去找可能存在大量创建线程的地方,优化掉;

  • OutOfMemoryError: GC overhead limit exceeded

JVM使用太多时间进行GC,并且效果不佳;

The parallel collector will throw an OutOfMemoryError if too much time is 
being spent in garbage collection: if more than 98% of the total time is spent 
in garbage collection and less than 2% of the heap is recovered, an 
OutOfMemoryError will be thrown. This feature is designed to prevent 
applications from running for an extended period of time while making little or 
no progress because the heap is too small. If necessary, this feature can be 
disabled by adding the option -XX:-UseGCOverheadLimit to the command 
line.
  • OutOfMemoryError: Requested array size exceeds VM limit

找到申请超大数组的地方,分析合理性,如果需要,增加JVM堆大小;

对拿到的heap进行分析

可以使用开源的MAT工具进行oom分析,不过需要首先拿到堆信息,也就是heap dump,然后倒入MAT进行分析;

MAT

重点关注Actions的Histogram和Reports的Leak Suspects,前者是将堆中按类型将每个类所创建的对象列出来,后者是MAT分析出来的内存泄漏结果,可以先从Leak Suspects中寻找到线索,然后在Histogram中来进行进一步的分析。

这里面有两个概念:

  • Retain Heap : 代表如果把该对象回收掉的话,一共可以回收多少空间,也就是包括了它引用的对象的大小,以及它引用的对象引用的对象的大小;
  • Shallow Heap : 表示该对象占用的空间,它所引用的对象的空间不计在内;

还有两个概念:

  • with outgoing references : 该对象引用的对象信息
  • with incoming reference : 引用该对象的信息

一般分析内存泄漏,如果Retain Heap很大,而Shallow Heap很小,则需要重点分析outgoing references,而如果Retain Heap和Shallow Heap差不多,则需要关注incoming references;

然后就是路由到GCRoots,之后就可以找代码分析问题了;

堆外内存泄漏

查看进程内存段:


pmap -x <pid> | sort -rn -k3 | head -30

监控进程内存申请系统调用:


strace -f -e "brk,mmap,munmap" -p <pid>

为了能让JVM响应System.gc(),不要在启动参数里面加:-XX:+DisableExplicitGC;

JAVA 线上故障排查全套路
Netty堆外内存泄露排查与总结
Java服务问题排查套路
CPU介绍
Spring Boot引起的堆外内存泄漏
操作系统内存管理方法
Java堆外内存回收原理
堆外内存回收机制
Java堆外内存
Java引用类型
堆外内存:DirectByteBuffer
DirectByteBuffer持有一个Cleaner虚引用,当DirectByteBuffer被GC回收时,Cleaner的clean方法会被触发:

Reference#cleaner
Reference handler
Reference#tryHandlePending

相关文章

网友评论

    本文标题:Java 内存 / cpu 问题排查方法

    本文链接:https://www.haomeiwen.com/subject/etsknctx.html