java应用cpu占用过高问题分析及解决方法
使用jstack分析java程序cpu占用率过高的问题
1,使用jps查找出java进程的pid,如3707
2,使用top -p 14292 -h观察该进程中所有线程的cpu占用。
[root@cp01-game-dudai-0100.cp01.baidu.com ~]# top -p 14292 -h top - 22:14:13 up 33 days, 7:29, 4 users, load average: 25.68, 32.11, 33.76 tasks: 113 total, 2 running, 111 sleeping, 0 stopped, 0 zombie cpu(s): 68.3%us, 6.3%sy, 0.0%ni, 20.2%id, 0.1%wa, 0.2%hi, 4.9%si, 0.0%st mem: 65965312k total, 65451232k used, 514080k free, 82164k buffers swap: 975864k total, 972052k used, 3812k free, 9714400k cached pid user pr ni virt res shr s %cpu %mem time+ command 15844 root 15 0 6889m 5.7g 4864 s 20.6 9.1 814:13.29 java 15848 root 15 0 6889m 5.7g 4864 s 13.0 9.1 460:25.17 java 15611 root 15 0 6889m 5.7g 4864 s 12.7 9.1 468:17.77 java 15613 root 15 0 6889m 5.7g 4864 s 11.7 9.1 479:40.45 java 15743 root 15 0 6889m 5.7g 4864 s 11.7 9.1 443:04.80 java 15612 root 15 0 6889m 5.7g 4864 s 11.0 9.1 453:43.68 java 15965 root 15 0 6889m 5.7g 4864 s 10.3 9.1 371:00.33 java 15490 root 15 0 6889m 5.7g 4864 s 7.7 9.1 255:32.74 java 15587 root 15 0 6889m 5.7g 4864 s 7.3 9.1 282:27.58 java 15590 root 15 0 6889m 5.7g 4864 s 7.3 9.1 205:48.37 java 15491 root 15 0 6889m 5.7g 4864 r 6.3 9.1 279:09.08 java 15689 root 15 0 6889m 5.7g 4864 s 5.7 9.1 251:42.36 java 16935 root 15 0 6889m 5.7g 4864 s 5.7 9.1 190:34.37 java 15665 root 15 0 6889m 5.7g 4864 s 5.3 9.1 250:07.34 java 16920 root 15 0 6889m 5.7g 4864 s 5.3 9.1 241:34.50 java 15671 root 15 0 6889m 5.7g 4864 s 5.0 9.1 239:49.97 java 15492 root 15 0 6889m 5.7g 4864 s 4.7 9.1 210:23.09 java 14322 root 16 0 6889m 5.7g 4864 s 4.3 9.1 107:39.61 java 14316 root 16 0 6889m 5.7g 4864 s 4.0 9.1 107:18.43 java 14317 root 16 0 6889m 5.7g 4864 s 4.0 9.1 107:29.13 java 15591 root 15 0 6889m 5.7g 4864 s 4.0 9.1 114:34.90 java 14313 root 16 0 6889m 5.7g 4864 s 3.7 9.1 107:12.70 java 14314 root 15 0 6889m 5.7g 4864 s 3.7 9.1 107:28.05 java 14319 root 16 0 6889m 5.7g 4864 s 3.7 9.1 107:27.43 java 14321 root 15 0 6889m 5.7g 4864 s 3.3 9.1 108:01.12 java 15589 root 15 0 6889m 5.7g 4864 r 3.0 9.1 109:01.91 java 15615 root 15 0 6889m 5.7g 4864 s 3.0 9.1 114:55.29 java 16808 root 15 0 6889m 5.7g 4864 s 2.7 9.1 279:05.03 java 14315 root 15 0 6889m 5.7g 4864 s 2.0 9.1 107:45.00 java 14320 root 15 0 6889m 5.7g 4864 s 2.0 9.1 107:48.30 java 15489 root 15 0 6889m 5.7g 4864 s 1.7 9.1 57:38.46 java 15670 root 15 0 6889m 5.7g 4864 s 1.3 9.1 5:55.43 java 14318 root 15 0 6889m 5.7g 4864 s 0.7 9.1 107:45.88 java 14826 root 15 0 6889m 5.7g 4864 s 0.7 9.1 25:07.64 java
3,找出cpu消耗较多的线程id,如15844,将15844转换为16进制0x3de4,注意是小写哦
4,使用jstack 14292|grep -a 10 0x3de4来查询出具体的线程状态。
[root@cp01-game-dudai-0100.cp01.baidu.com ~]# jstack 14292|grep -a 10 0x3de4 "pool-52-thread-1" prio=10 tid=0x000000005a08e000 nid=0x3de4 waiting on condition [0x00002ae63d917000] java.lang.thread.state: waiting (parking) at sun.misc.unsafe.park(native method) - parking to wait for <0x00000006f9a0a110> (a java.util.concurrent.locks.abstractqueuedsynchronizer$conditionobject) at java.util.concurrent.locks.locksupport.park(locksupport.java:156) at java.util.concurrent.locks.abstractqueuedsynchronizer$conditionobject.await(abstractqueuedsynchronizer.java:1987) at java.util.concurrent.linkedblockingqueue.take(linkedblockingqueue.java:399) at java.util.concurrent.threadpoolexecutor.gettask(threadpoolexecutor.java:947) at java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:907) at java.lang.thread.run(thread.java:662)
通过这些线程状态便可基本定位问题之所在。
解决办法:
方法1
1.jps 获取java进程的pid。
2.jstack pid >> java.txt 导出cpu占用高进程的线程栈。
3.top -h -p pid 查看对应进程的哪个线程占用cpu过高。
4.echo “obase=16; pid” | bc 将线程的pid转换为16进制,大写转换为小写。
5.在第二步导出的java.txt中查找转换成为16进制的线程pid。找到对应的线程栈。
6.分析负载高的线程栈都是什么业务操作。优化程序并处理问题。
方法2
1.使用top 定位到占用cpu高的进程pid
top
通过ps aux | grep pid命令
2.获取线程信息,并找到占用cpu高的线程
ps -mp pid -o thread,tid,time | sort -rn
3.将需要的线程id转换为16进制格式
printf "%x\n" tid
4.打印线程的堆栈信息
jstack pid |grep tid -a 30
总结
以上就是本文关于java应用cpu占用过高问题分析及解决方法的全部内容,希望对大家有所帮助,如果有什么疑问,可以随时留言,小编会及时回复大家的。感谢朋友们对网站的支持。
上一篇: Android实现蒙板效果