今天收到客服报警,系统无法登录。登录服务器后看到tomcat进程存在,top命令发现进程占用CPU2000%多。该服务里面跑了很多线程,于是想找到是谁引起的


1、首先dump出该进程的所有线程及状态
使用命令 jstack PID 命令打印出CPU占用过高进程的线程栈.


    jstack -l <PID> > PID.stack

将进程的线程栈输出到了文件


2、使用top命令找到耗cpu的线程
    使用top -H -p PID 命令查看对应进程是哪个线程占用CPU过高.

    top -H -p <PID>


3. 将线程的pid 转成16进制,比如22138 = 567a

        printf "%x\n" <PID>

   

4. 到第一步dump出来的文件中搜索得到的16进制线程号,就知道是哪个线程了

"schedulerFactory_Worker-29" prio=10 tid=0x00002aaab0505000 nid=0x567a runnable [0x000000004db47000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:129)
        at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114)
        at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161)
        at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189)
        - locked <0x00000007bc90fdb0> (a com.mysql.jdbc.util.ReadAheadInputStream)
        at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2549)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2991)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3532)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
        at