Skip to main content

 路由器设置 > 新闻资讯 >

java应用 CPU使用率过高问题排查

2013-12-31 01:00 浏览:

  最近碰到几次java应用某台机器cpu比较高的情况,而且重启后基本上都会恢复正常。

  正常情况下:

  应用使用CPU在 :30%--40%

  异常情况下:

  CPU利用率在:80%---90%

  在网上查了下,一般java应用cpu过高基本上是因为

  1.程序计算比较密集

  2.程序死循环

  3.程序逻请求堵塞

  分析步骤:

  1.登陆应用机器,top命令查看 当前占用cpu资源最多的,一般排名第一位肯定是java进程

  一般也可能存在多个java进程

  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

  17766 nobody 20 0 5818m 2.4g 14m S 51.8 65.2 144:09.75 java

  2.查看进程的哪个线程占用cpu比较高

  取线上另外一台正常情况下利用cpu比较高的应用:通过

  ps -mp PID号 -o THREAD,tid,time

  可以可看到线程ID和线程使用的时间。。。

  # ps -mp 18429 -o THREAD,tid,time

  USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME

  spider 93.8 - - - - - - 5-21:06:57

  spider 0.0 19 - futex_ - - 18429 00:00:00

  spider 93.7 19 - - - - 18430 5-21:01:16

  spider 0.0 19 - futex_ - - 18431 00:00:10

  TID为18430的线程利用cpu资源比较多,怎么能看到这个线程在干什么呢?

  需要将18430转换为16进制,便于在jvm堆栈中查找。

  printf "%x\n" 18430

  通过jstack命令来查看下当前内存状态:

  #sudo -u nobody jstack 18429 |grep 47fe -A 60 |less (或者切换到java程序运行的账户)

  "main" prio=10 tid=0x00002aff38005800 nid=0x47fe runnable [0x00002aff35db4000]

  java.lang.Thread.State: RUNNABLE

  at java.net.PlainSocketImpl.socketAvailable(Native Method)

  at java.net.PlainSocketImpl.available(PlainSocketImpl.java:472)

  - locked <0x00000007434484b0> (a java.net.SocksSocketImpl)

  at java.net.SocketInputStream.available(SocketInputStream.java:217)

  at com.mysql.jdbc.util.ReadAheadInputStream.available(ReadAheadInputStream.java:231)

  at com.mysql.jdbc.MysqlIO.clearInputStream(MysqlIO.java:940)

  剩下的事情,如果是自己写的代码就很好办了。

  如果是有对应开发人员,接下来就是找开发人员确认这段代码是否可以优化。