我有一个java程序,在运行大约20-30分钟后开始变得迟钝并使用太多CPU,并且随着时间的推移继续变得更糟。
我使用Open JRE 8_151在Ubuntu Linux 17.10上。我确认在使用Oracle JRE 8_131的Windows上也会出现此错误(我假设为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%的处理器能力来进行垃圾收集。
我从哪里开始尝试调试此问题?我可以开始禁用活动的运行线程,以查看问题是否消失,但鉴于它
这可能需要一段时间,所以我希望有一些更聪明的东西,就像我上面尝试过的那样。
有什么建议吗?
P.S。我从不在我的代码中调用System.gc()。
答案 0 :(得分:2)
检查是否有大量长寿命对象。对于有几代人的垃圾收集器来说,这是一个致命的案例。在这种情况下,请尝试使用G1 GC。