java - 如何弄清楚为什么垃圾收集器使用了我 90% 的 CPU?

标签 java debugging

我有一个 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 的运行线程以查看问题是否消失,但考虑到它

  1. 不会在每次发射时都出现;和
  2. 需要 20-30 分钟才能开始出现

这可能需要一段时间,所以我希望有一些更聪明的东西,就像我上面尝试的那样。

有什么建议吗?

附言我从不在我的代码中调用 System.gc() 。

最佳答案

检查您是否有大量长生命周期对象。对于世代垃圾收集器来说,这是一个致命的案例。在这种情况下尝试使用 G1 GC。

关于java - 如何弄清楚为什么垃圾收集器使用了我 90% 的 CPU?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48001266/

相关文章:

java - 如何在 Java 中高效存储一组元组/对

java - 砖 block 位置,在打砖 block 游戏中,使用 Java 中的数组

ios - 找不到崩溃异常原因的类型:EXC_BREAKPOINT(SIGTRAP)

javascript - 如何在谷歌应用程序脚本中调试客户端 javascript(在 html 页面中)

visual-studio - 更改远程桌面键盘快捷方式

Java队列内存大小限制

java - 如何正确设置ant中的类路径?

java - 在 jUnit 的 assertEquals() 方法中计算 expected_value 的最佳方法是什么

java - 远程监控所有 Android 设备事件

javascript - 如何在 Window 的嵌入式浏览器中调试 Javascript?