Skip to content

Commit 5f97852

Browse files
committed
java CPU100%占用
1 parent bd26c7c commit 5f97852

File tree

4 files changed

+132
-0
lines changed

4 files changed

+132
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Senior Java engineer interview exams in 2019
1919
* [zookeeper选举机制](https://www.linuxidc.com/Linux/2018-09/154117.htm)
2020

2121
* [Redis集群方式有哪几种](readme/redis-cluster-strategies.md)
22+
23+
* [如何排查Java的CPU性能问题-CPU100%占用](readme/cpu100percent.md)
2224

2325

2426
<hr/>

code/CpuTest.class

298 Bytes
Binary file not shown.

code/CpuTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
public class CpuTest {
2+
public static void main(String[] args) {
3+
int i= 0;
4+
5+
while (true) {
6+
i++;
7+
// if (i == Integer.MAX_VALUE) {
8+
//// System.out.println("--reset---");
9+
// i = 0;
10+
// }
11+
}
12+
13+
}
14+
}

readme/cpu100percent.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# 如何排查Java的CPU性能问题-CPU100%占用
2+
3+
## 排查步骤
4+
5+
例如一个java进程的cpu占用达到99.3%
6+
7+
```text
8+
top - 14:56:39 up 199 days, 4:55, 3 users, load average: 2.24, 2.35, 2.27
9+
Tasks: 81 total, 1 running, 76 sleeping, 4 stopped, 0 zombie
10+
%Cpu(s):100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
11+
KiB Mem : 1883492 total, 100904 free, 968764 used, 813824 buff/cache
12+
KiB Swap: 0 total, 0 free, 0 used. 727152 avail Mem
13+
14+
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
15+
8999 root 20 0 2460600 17060 10116 S 99.3 0.9 31:51.17 java
16+
23996 root 0 -20 138996 17416 6260 S 0.3 0.9 375:12.90 AliYunDun
17+
1 root 20 0 190708 2492 1284 S 0.0 0.1 1:32.14 systemd
18+
2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd
19+
3 root 20 0 0 0 0 S 0.0 0.0 0:52.57 ksoftirqd/0
20+
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
21+
7 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
22+
```
23+
24+
1.top
25+
找到占用cpu太高的java进程的pid
26+
假如是8999
27+
28+
2.查看pid对应进程的线程的资源占用情况
29+
```text
30+
ps -mp 8999 -o THREAD,tid,time
31+
```
32+
33+
例如
34+
```text
35+
[root@iz8vb3nxwmck3z1ruwn8euz 9000]# ps -mp 8999 -o THREAD,tid,time
36+
USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME
37+
root 0.0 - - - - - - 00:37:34
38+
root 0.0 19 - futex_ - - 8999 00:00:00
39+
root 0.0 19 - futex_ - - 9000 00:00:05
40+
root 0.0 19 - futex_ - - 9001 00:01:27
41+
```
42+
43+
假如最高的tid是9000 (线程id)
44+
45+
3.tid转化成十六进制
46+
```text
47+
printf "%x\n" 9000
48+
2328
49+
```
50+
51+
4.jstack查看线程栈日志
52+
例如
53+
54+
```text
55+
[root@iz8vb3nxwmck3z1ruwn8euz 9000]# jstack 8999 |grep 2328 -A 30
56+
"DestroyJavaVM" #36 prio=5 os_prio=0 tid=0x00007f5e18009800 nid=0x2328 waiting on condition [0x0000000000000000]
57+
java.lang.Thread.State: RUNNABLE
58+
59+
"pool-3-thread-3" #35 prio=5 os_prio=0 tid=0x00007f5dec05b000 nid=0x234c waiting on condition [0x00007f5de59ea000]
60+
java.lang.Thread.State: WAITING (parking)
61+
at sun.misc.Unsafe.park(Native Method)
62+
- parking to wait for <0x00000000f56abee8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
63+
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
64+
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
65+
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
66+
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
67+
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
68+
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
69+
at java.lang.Thread.run(Thread.java:748)
70+
```
71+
72+
命中的位置是
73+
nid=0x2328
74+
75+
nid指的是native thread id (linux native light weight process id)
76+
这个日志会显示报错的java代码的那一行。
77+
78+
关于grep里的参数"-A"的说明
79+
-A<显示列数> 除了显示符合范本样式的那一行之外,并显示该行之后的内容。
80+
81+
## 测试程序
82+
程序的cpu占用达到80%~100%这种情况,一般可能发送在大量的for循环或者while循环中(也可能是死循环中的反复计算)
83+
84+
demo程序见[CpuTest.java](/code/CpuTest.java)
85+
86+
贴出代码
87+
```java
88+
public class CpuTest {
89+
public static void main(String[] args) {
90+
int i= 0;
91+
92+
while (true) {
93+
i++;
94+
// if (i == Integer.MAX_VALUE) {
95+
//// System.out.println("--reset---");
96+
// i = 0;
97+
// }
98+
}
99+
100+
}
101+
}
102+
103+
```
104+
105+
先编译程序,然后运行CpuTest.class,命令如下
106+
```shell
107+
#cd code/
108+
109+
#javac CpuTest.java
110+
#ls
111+
CpuTest.class CpuTest.java
112+
113+
#java CpuTest
114+
```
115+
116+
然后用top命令可以看到有个java进程cpu占用特别大。

0 commit comments

Comments
 (0)