如何精准排查线上JVM CPU占用百分百的原因

JVM虚拟机 artisan 1063℃ 0评论

对于线上服务难免会出现CPU占用百分之百的情况,此时就需要块找到问题所在,但是如何能够精准快速找到原因呢?

问题现象

收到监控报警,看了一下资源使用情况:
JAVA进程占用CPU100

可以发现17629进程占用CPU资源接近百分之百,通常是存在问题的,但是如何精准判断到底是哪一行代码产生的问题呢?

排查问题

排查问题就需要使用top命令了,此时就需要简单了解一下top命令的使用了: top命令指定-H可以以线程的粒度显示资源占用,指定-H之后每一行记录则表示一个操作系统线程id(native thread id);除此之外还可以指定-p指定进程id,指定进程id之后就可以看单个进程的资源占用情况了。再次执行top命令查看资源使用:

  top -H -p 17629

执行结果
top2
此时的PID表示的线程id,但是这个线程id是操作系统的线程id,而不是JVM线程的id。那如何能将该线程ID对应上JVM线程的id呢?

操作系统线程(native thread id)如何映射JVM线程id?

为了映射JVM线程,就需要首先找到JVM线程有哪些线程?如何查看JVM线程呢?可以通过查看JVM进程的堆栈信息找到线程,具体如下:使用java带的jstack工具即可查看JVM进程的堆栈信息。

 jstack  17629 

执行结果:
jstack
可以看到jstack结果中每一个线程都有一个nid,nid则是native thread id,但nid是16进制的,我们可以将 top -H -p 17629 中的id转化为16进制:

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                     
   17639 root      20   0 2439m  28m  11m R 98.2  1.4  10:48.86 java 

17639转16进制为0x44e7,我们可以去jstack中寻找nid为0x44e7的线程,线程信息如下:

 "whileTure-worker" #8 prio=5 os_prio=0 tid=0x00007f79ac0ca000 nid=0x44e7 runnable [0x00007f79b1b86000]
   java.lang.Thread.State: RUNNABLE
 at WhileTrue$1.run(WhileTrue.java:14)
 at java.lang.Thread.run(Thread.java:748)

此时就可以定位Java线程名字为whileTure-worker了,同时执行栈信息也有,可以判断问题出现在:WhileTrue.java:14 。后续问题解决也就容易了。

参考:top命令使用详情参见https://linux.die.net/man/1/top

转载请注明:Java工匠师 » 如何精准排查线上JVM CPU占用百分百的原因

喜欢 (8)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址