我有一个 Java 程序在运行大约 20-30 分钟后开始变得迟缓并且使用过多的 CPU,并且随着时间的推移继续变得更糟。
我在 Ubuntu Linux 17.10 上使用 Open JRE 8_151。我确认此错误也发生在使用 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% 的处理器能力来进行垃圾收集。
从这里我应该从哪里尝试调试这个问题?我可以开始禁用 Activity 的运行线程以查看问题是否消失,但考虑到它
- 不会在每次发射时都出现;和
- 需要 20-30 分钟才能开始出现
这可能需要一段时间,所以我希望有一些更聪明的东西,就像我上面尝试的那样。
有什么建议吗?
附言我从不在我的代码中调用 System.gc() 。
最佳答案
检查您是否有大量长生命周期对象。对于世代垃圾收集器来说,这是一个致命的案例。在这种情况下尝试使用 G1 GC。
关于java - 如何弄清楚为什么垃圾收集器使用了我 90% 的 CPU?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48001266/