我有一个Java程序,在运行20-30分钟后开始变得卡顿并使用过多的CPU,随着时间的推移情况越来越糟糕。
我使用的是Ubuntu Linux 17.10,使用Open JRE 8_151。我确认这个bug也会出现在Windows上,使用Oracle JRE 8_131(我认为8_151也会有这个问题)。
我等了大约45分钟,直到程序使用了很多CPU(约90%),然后采取以下措施尝试确定我的程序中哪个线程是问题所在:
所以是垃圾收集器在消耗我的CPU。这对我来说并没有什么帮助,因为我不知道哪个线程正在生成被回收的对象,或者为什么它要消耗85%的处理器性能进行垃圾收集。
我该从哪里开始调试此问题?我可以开始禁用活动运行的线程,看看问题是否消失,但考虑到:
1. 不是每次启动都会出现; 2. 需要20-30分钟才会开始出现。
这可能需要一段时间,所以我希望有更聪明的方法,就像我上面尝试的那样。
有什么建议吗?
附言:我从未在我的代码中调用System.gc()。
我使用的是Ubuntu Linux 17.10,使用Open JRE 8_151。我确认这个bug也会出现在Windows上,使用Oracle JRE 8_131(我认为8_151也会有这个问题)。
我等了大约45分钟,直到程序使用了很多CPU(约90%),然后采取以下措施尝试确定我的程序中哪个线程是问题所在:
ps aux
#Visually confirm the process is using 90% and note ID -- 20316
top -p20316
#confirm usage, in top it says 366.3%; 4-core processor so this makes sense
[while in top] press shift + H
# See four threads each using about 85%
20318
20319
20320
20321
# Convert those to hex
20318 -> 0x4f5e
20319 -> 0x4f5f
20320 -> 0x4f60
20321 -> 0x4f61
[Exit top]
jstack -l 20316 | less
[press / and search for those hex thread ids]
# Get the following results:
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007ff9f8020000 nid=0x4f5e runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007ff9f8021800 nid=0x4f5f runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007ff9f8023800 nid=0x4f60 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007ff9f8025000 nid=0x4f61 runnable
所以是垃圾收集器在消耗我的CPU。这对我来说并没有什么帮助,因为我不知道哪个线程正在生成被回收的对象,或者为什么它要消耗85%的处理器性能进行垃圾收集。
我该从哪里开始调试此问题?我可以开始禁用活动运行的线程,看看问题是否消失,但考虑到:
1. 不是每次启动都会出现; 2. 需要20-30分钟才会开始出现。
这可能需要一段时间,所以我希望有更聪明的方法,就像我上面尝试的那样。
有什么建议吗?
附言:我从未在我的代码中调用System.gc()。
-XX:+UseG1GC
- Hash Jang