java程序造成linux服务器cpu使用率非常高的排除方法

最近一段时间  某台服务器上的一个应用总是隔一段时间就自己挂掉      用top看了看  从重新部署应用开始没有多长时间CPU占用上升得很快  

排查步骤

1.使用top 定位到占用CPU高的进程PID

  top 

2.通过ps aux | grep PID命令

  获取线程信息,并找到占用CPU高的线程

  ps -mp pid -o THREAD,tid,time | sort -rn 

3.将需要的线程ID转换为16进制格式

  printf "%x\n" tid

4.打印线程的堆栈信息  到了这一步具体看堆栈的日志来定位问题了

  jstack pid |grep tid -A 30

----------------------------------------------------------------------------  华丽的分割线  ------------------------------------------------------------------------------------------------------------------

top     可以看出PID  733进程 的占用CPU  172%

查找进程733下的线程  可以看到TID 线程775占用了96%且持有了很长时间  其实到这一步基本上能猜测到应该是    肯定是那段代码发生了死循环

ps -mp 733 -o THREAD,tid,time | sort -rn

线程ID转换为16进制格式

printf "%x\n" 775

 查看java  的堆栈信息

jstack 733 |grep 307 -A 30

显然是 SmsQueueServiceImpl 中的produceMissSms   和 consumeMissSms  方法有问题

ps -mp 21053 -o THREAD,tid,time | sort -rn

 printf "%x\n" 21059
5243

有时候jstack打印的数据非常少

jstack 21053|grep 5243 -A 30有时候提示

Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding

可以使用

su - root -c "/opt/jvm/jdk1.8.0_192/bin/jstack 3749|grep 34d8 -A 30"

强制指定运行jstack的用户,以及指定jstack运行的路径。 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f0374022800 nid=0x5243 runnable 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f0374024000 nid=0x5244 runnable 

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007f0374026000 nid=0x5245 runnable 

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007f0374027800 nid=0x5246 runnable 

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007f0374029800 nid=0x5247 runnable 

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007f037402b000 nid=0x5248 runnable 

"VM Periodic Task Thread" os_prio=0 tid=0x00007f0374dda800 nid=0x526b waiting on condition 

JNI global references: 2946

没啥有用的信息

jstat -gcutil pid 2000 10(显示个数)

jstat -gcutil 14063 2000 10

  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
  0.00   0.00 100.00  99.99  26.31     42   21.917   218 1484.830 1506.747
  0.00   0.00 100.00  99.99  26.31     42   21.917   218 1484.830 1506.747
  0.00   0.00 100.00  99.99  26.31     42   21.917   219 1496.567 1518.484
  0.00   0.00 100.00  99.99  26.31     42   21.917   219 1496.567 1518.484
  0.00   0.00 100.00  99.99  26.31     42   21.917   219 1496.567 1518.484
  0.00   0.00 100.00  99.99  26.31     42   21.917   219 1496.567 1518.484
  0.00   0.00 100.00  99.99  26.31     42   21.917   219 1496.567 1518.484
  0.00   0.00 100.00  99.99  26.31     42   21.917   220 1505.439 1527.355
  0.00   0.00 100.00  99.99  26.31     42   21.917   220 1505.439 1527.355
  0.00   0.00 100.00  99.99  26.31     42   21.917   220 1505.439 1527.355

从输出信息可以看出,Eden区内存占用100%,Old区内存占用99.99%,Full GC的次数高达220次,并且频繁Full GC,Full GC的持续时间也特别长,平均每次Full GC耗时6.8秒(1505.439/220)。根据这些信息,基本可以确定是程序代码上出现了问题,可能存在不合理创建对象的地方

还有个程序是arthas下面一个监测脚本叫show-busy-java-threads

直接运行./show-busy-java-threads可用列出cpu最高的前5个线程

再说下arthas是一个很好用的监测程序arthas-boot.jar

java -jar arthas-boot.jar 启动起来以后选择需要监控的java编号

可以使用的命令dashboard可以看目前运行的一个图形界面线程监控

thread可以列出现在占用最高的线程列表,thread -n 3列出占用最高的线程详情

有时候cpu 100%以后运行不了任何打印线程的命令,多试几次,再cpu稍微降低的时候运行上述命令,只要能打印一次就可以找到代码故障位置进行排查。

还可以用jmap -dump:live,format=b,file=heap_dump pid保存一下dump文件。然后在pc上面用MemoryAnalyzer分析一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值