如何弄清楚为啥垃圾收集器使用了我 90% 的 CPU?
Posted
技术标签:
【中文标题】如何弄清楚为啥垃圾收集器使用了我 90% 的 CPU?【英文标题】:How to figure out why the garbage collector is using 90% of my CPU?如何弄清楚为什么垃圾收集器使用了我 90% 的 CPU? 【发布时间】:2017-12-28 03:30:43 【问题描述】:我有一个 java 程序在运行大约 20-30 分钟后开始变得迟钝并使用过多的 CPU,并且随着时间的推移继续恶化。
我在使用 Open JRE 8_151 的 Ubuntu Linux 17.10 上。我确认此错误也发生在使用 Oracle JRE 8_131(我假设为 8_151)的 Windows 上。
我等了大约 45 分钟,直到程序使用了大量 CPU(大约 90%),并采取了以下操作来尝试识别我的程序中的哪个线程正在占用大量 CPU:
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% 的处理器能力来进行垃圾收集。
我该去哪里尝试调试这个问题?我可以开始禁用活动运行的线程以查看问题是否消失,但考虑到它
-
不会在每次启动时都显示;和
需要 20-30 分钟才能开始显示
这可能需要一些时间,所以我希望有一些更聪明的东西,就像我上面尝试的那样。
有什么建议吗?
附:我从不在我的代码中调用 System.gc() 。
【问题讨论】:
【参考方案1】:检查您是否有大量的长寿命对象。对于具有世代的垃圾收集器来说,这是一个致命的案例。在这种情况下,请尝试使用 G1 GC。
【讨论】:
我愿意。我有大约 6000 个小但寿命长的物体。如何指定使用 G1 GC? 使用-XX:+UseG1GC
我现在就试一试,然后告诉你进展如何。真心希望能采纳你的回答,谢谢!
@JoshuaD 有帮助吗?我也遇到了同样的问题。
@Harshit Gupta 是的,这很有帮助。我还在 linux 上使用了一个进程检查器来查看哪些线程在做什么。以上是关于如何弄清楚为啥垃圾收集器使用了我 90% 的 CPU?的主要内容,如果未能解决你的问题,请参考以下文章