Linux下java进程CPU占用率高-分析方法


今天登陆同事的一台gateway 开始以为hive环境登陆不了了,仔细一看看了下是因为机器很卡,我每次等几秒没登陆就ctrl+c了,看了下是有个java进程cpu:340.4%  mem:14.6% 

一般解决方法是通过top命令找出消耗资源高的线程id,利用strace命令查看该线程所有系统调用 

1. 通过top命令找到可疑进程PID 

top 一下 

可以看出java进程CPU利用率一直保持100%,稳居不下,找到PID 24138 

2. 找出消耗资源最高的线程 

top -H -p  29580  可以不用第一步,直接执行命令 top -H ,就可以查看到消耗资源最高的线程 

top - 20:42:01 up 633 days,  9:30,  9 users,  load average: 6.75, 8.32, 15.86 

Tasks:  28 total,   2 running,  26 sleeping,   0 stopped,   0 zombie 

Cpu(s): 42.4%us,  4.3%sy,  0.0%ni, 53.1%id,  0.0%wa,  0.0%hi,  0.1%si,  0.1%st 

Mem:   7680000k total,  5774940k used,  1905060k free,   400792k buffers 

Swap:  2096472k total,   876580k used,  1219892k free,  1727652k cached 

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

29679 baishou   16   0 1560m 1.1g  18m R 72.0 15.3 115:41.08 java                                                                                                               

29678 baishou   15   0 1560m 1.1g  18m R 63.3 15.3 118:44.99 java                                                                                                               

29673 baishou   15   0 1560m 1.1g  18m S  1.0 15.3   0:59.72 java                                                                                                               

29677 baishou   15   0 1560m 1.1g  18m S  1.0 15.3   1:01.34 java                                                                                                               

3. 查看这个线程所有系统调用 

strace -p 29679 

read(114, "\0\225\0\0\6\0\0\0\0\0\10\0\0\4\3\0\0\0p\365\1_\0\0\0\0\0\0\0\0\0\4"..., 2064) = 149
write(114, "\7\333\0\0\6\0\0\0\0\0\3\201r\4\0\0\0\0\0\0\0 B\25\274\252*\0\0\275.\0"..., 2011) = 2011
write(114, "\7\333\0\0\6\0\0\0\0\0Adddddc\2\301!\4\302dQQ\3\300R\37\3\300c"..., 2011) = 2011
write(114, "\7\333\0\0\6\0\0\0\0\0000\6\305\6\1JdK\ttb1521841\0010\1\200"..., 2011) = 2011
write(114, "\7\333\0\0\6\0\0\0\0\0000\6\305\6\1K6\27\ttb1533113\0010\1\200"..., 2011) = 2011
write(114, "\7\333\0\0\6\0\0\0\0\0<\0|0\6\305\6\1L\23\20\ttb1518437\1"..., 2011) = 2011
write(114, "\7\333\0\0\6\0\0\0\0\0\0010\1\200\1\200\2\301)\1\200\2\301\2\1\200\1\200\1\200\1\200"..., 2011) = 2011
write(114, "\0\34\0\0\6\0\0\0\0\0\200\1\200\1\200\1\200\n\300\31\20F\10\27#\23\23)", 28) = 28
read(114, "\0\225\0\0\6\0\0\0\0\0\10\0\0\4\3\0\0\0q\365\1_\0\0\0\0\0\0\0\0\0\4"..., 2064) = 149
write(114, "\7\333\0\0\6\0\0\0\0\0\3\201s\4\0\0\0\0\0\0\0 B\25\274\252*\0\0\311.\0"..., 2011) = 2011


发现有大量写操作,应该是由datax任务在跑。 

+++++++++++++++++++++++++++++++++++++++++++++++++++ 

++++++++++++++如果是web应用,可以继续打印线程的堆栈信息+++++++++ 

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

printf "%x\n" 29679 

73ef 

最后打印线程的堆栈信息: 

jstack 29679|grep 73ef -A 30 


技术链接