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

时间:2021-07-08 03:35:02

今天登陆同事的一台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