jvmCPU问题的排查

<一>试题1:某服务器CPU使用率达到99%,排查是哪个程序的哪个线程导致的高CPU。

思路:

1.1、先找到耗CPU高的进程;

1.2、找到耗CPU高的线程;

1.3、找到耗CPU高的线程对应的业务代码;

操作:

1.1、执行“top -c”命令,显示进程运行信息列表,键入大写P,按CPU使用率降序排列:

1.2、获取到进程PID为10765的进程,使用CPU资源最高19.9%;

至此,已找到耗CPU最高的进程,进程PID为10765,后续命令中需要使用到。

2.1、一个进程内有很多线程,执行“top -Hp 10765”,显示进程ID为10765线程列表,键入大写P后,按CPU使用率降序排列:

2.2、其中,PID为10804线程,CPU使用率最高2.3%;

2.3、将线程ID(10804)按16进制展示,执行指令“printf "%x\n" 10804”:

至此,找到了CPU使用率最高的线程ID为10804,并获取到10804的16进制标识:2a34 

(转为16进制,是因为jstack打印出的线程栈信息中,线程id是通过16进制展示的)

3.1、通过jstack检索到进程(进程ID=10765)中,最耗CPU的线程(线程ID=2a34)的线程栈信息;

执行指令“jstack 10765 | grep "2a34" -C5 --color”:

至此,找到了耗CPU高的线程对应的线程名称“AsyncLogger-1”,而这个线程名称是我们业务代码中给线程取的名称,可以快速定位到业务代码。

tips:给线程取一个与业务处理相关的名称,对快速定位问题尤为重要。

如果我们没有给线程取名称“AsyncLogger-1”,那打印出来的线程名称可能是:

通过不知名的线程名称“pool-5-thread-1”,以及只包含jdk代码的线程栈信息,我们无法定位到业务代码。

<二>试题二:某java应用大量消耗内存,导致OutOfMemoryError

思路:

1、什么对象消耗内存最大;

2、是否创建了太多的线程;

3、新生的、老年代现在内存使用情况,确认是不是整体内存分配太小了;

4、实时查看新生的、老年代内存使用情况,GC情况

5、代码层检查,是否有大对象创建?需要调用close()dispose()来回收的资源是否回收了?

操作:

1、执行“jmap -histo:live 10765 | more”命令,以表格的方式显示存活对象的信息(已按对象所占bytes大小进行降序排列):

其中,10765为进程ID,更多用法,通过“man jmap”寻求帮助。

内存最多的对象类型org.apache.logging.log4j.core.async.RingBufferLogEvent,

总共18874368byte (18M),例子中属于正常使用。

tips如果发现某类对象内存很大(几个G的大小),很可能是有问题的。

基本都是因为:该类对象创建太多,一直未释放。比如:使用完IO资源后,调用close()接口关闭、释放资源;比如:消费者消费速度慢(或停止消费了),而生产者不断往队列中投递任务,导致队列中任务累积过多,任务对象占用内存太多而产生OutOfMemoryError;

2、执行“pstree -p 10765 | wc -l”,查看进程内的线程数

其中,10765为进程ID。

每个线程需要分配线程栈内存,创建线程太多,可能导致OutOfMemoryError。

3、执行jmap -heap 10765”,查看堆(新生代、老年代)内存分配大小及使用情况

4、执行“jstat -gc 10765 1000”,查看各个区内存使用情况及GC情况

其中,10765为进程ID,1000为数据刷新间隔的毫秒数

具体字段含义,通过“man jstat”寻求帮助。

主要查看:

EC:Eden区容量,EU:Eden区已使用量,OC:Old区容量,OU:Old区已使用量;

YGC:YongGC次数,YGCT:YongGC耗时,FGC:FullGC次数,FGCT:FullGC耗时;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值