MyBlog


JAVA CPU占用过高问题排查(linux)

<p>[TOC]</p> <h1>背景</h1> <p>最近发现有一个服务在服务器上无响应,到服务器上一看,好家伙,java进程CPU一直100%以上 <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/c9a4bac7221d78bf469976e4fc5ba33f?showdoc=.jpg" alt="" /> 简单记录下我对这个问题的跟踪</p> <p>首先当然要看下具体是java中哪个线程一直在占用cpu时间哈(说明下,我的java进程号是 26178)</p> <h1>1.根据java进程ID进行CPU占用排查</h1> <p><code>ps -mp 26178 -o THREAD,tid,time | sort -rn | more (sort -rn 以数值的方式进行逆序排列)</code></p> <p><img src="https://www.showdoc.cc/server/api/common/visitfile/sign/a2fadd396c0643a51297d5405bca5287?showdoc=.jpg" alt="" /></p> <h1>2.根据1中查找到的CPU最高的排序中的结果,找出几个占用cpu时间比较高的TID</h1> <p>比如这里的26217 26182 26183将进程ID转换为16进制,printf &quot;%x\n&quot; 26217</p> <h1>3.再使用jstack命名查询是哪个线程</h1> <p>TID十进制-》十六进制 26217 -》 6669 26182 -》 6646 26183 -》 6647 拿到线程ID的16进制之后,就可以从jstack中查找具体是对应的线程 <code>jstack 26178 |grep 6669 -A 30</code> <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/23b88f9503a6ace32b72c84e686c79aa?showdoc=.jpg" alt="" /> 可以发现,几个占用大量cpu时间的线程都是GC相关。</p> <h1>4.再次确认gc信息,查看gc time等信息,jstat -gcutil 26178 1000 100</h1> <p><img src="https://www.showdoc.cc/server/api/common/visitfile/sign/e179d87a5fd4977e3855cb5065480d2d?showdoc=.jpg" alt="" /> 可以看到s0、s1、eden、old、metaspace都已经爆了,并且FGC次数一直在增加,但是却没有回收到任何空间,导致FGC一直在跑,进入循环,应该是程序存在内存泄露咯。(gc有日志,后续有空再出一篇简单分析gc日志的blog)</p> <h1>5.jmap -histo:live 26178 | more 简单查看对象的大小数目</h1> <h1>6.dump内存,使用工具分析内存镜像,jmap -dump:live,format=b,file=problem.bin 26178</h1> <h1>7.使用MAT(Memory Analyzer tool)进行数据分析,注意,如果步骤6中dump出来文件过大,需要设置MAT配置文件(MemoryAnalyzer.ini)的xmx参数的大小。</h1>

页面列表

ITEM_HTML