10

我们有一个 JVM 进程,它很少将 CPU 固定在 100%,看起来(根据 visualgc)一个几乎耗尽的堆。我们的假设是,该进程正在大量 GC'ing 导致 CPU 峰值,这会影响整个系统的整体健康状况(由其他 JVM 做不同的事情)。

此过程并不重要,可以重新启动。有没有办法通过命令行来调整 JVM,让它自食其力,而不是继续 GC'ing 并导致整个盒子受苦?

值得注意的是,我们没有收到 OOMExceptions,因此堆并没有完全耗尽,但我们认为几乎没有。

或者,可以让我们深入了解 JVM 中的实际使用 CPU 的方式是确认/拒绝我们的 GC 假设?

4

5 回答 5

4

我们可以从

1):选项 -XX:+PrintGCTimeStamps 将在每个集合开始时添加一个时间戳。这对于查看垃圾收集发生的频率很有用。

使用上述选项,我们可以粗略估计您是否认为该进程是英雄 GC'ing 导致 CPU 峰值。

如果您的假设是正确的,那么开始调整您的 GC 。

 Both parallel collector and Concurrent Collector will throw an OutOfMemoryError if too much time is being
 spent in garbage collection: if more than 98% of the total time is spent in garbage collection and 
less than 2% of the heap is recovered, an OutOfMemoryError will be thrown. the option X:-UseGCOverheadLimit 
 is enabled by default for both Parallel and concurrent collector . Check whether this option is disabled in
 your system .  

有关 JVM 中 Gc 调优的更多信息,请参阅内容,对于 vm 调试选项,请检查此内容

于 2013-01-18T09:37:50.917 回答
3

并行和并发收集器有一个“开销限制”,可能会做你想做的事:

如果超过 98% 的总时间花在垃圾收集上,而回收的堆少于 2%,则会抛出 OutOfMemoryError

有关详细信息,请参阅http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

于 2013-01-17T19:25:34.583 回答
2

最好的办法是找出内存泄漏并修复它。

退出高内存使用的简单方法:

if(Runtime.getRuntime().totalMemory()>100*1024*1024)
    System.exit(0);
于 2013-01-17T18:49:46.213 回答
2

尝试查看当前在 JVM 中运行的进程。

  • jstack您一起可以进行线程转储(还有其他方法可以做到这一点)
  • 您可以查看 JVM的jvisualvm当前状态(占用一些资源)
  • 也打开verbosegc(证明你假设GC是频繁的)
于 2013-01-17T18:50:22.017 回答
1

您需要找到一种方法来收集有关 GC 工作的一些统计信息。实际上有一些方法可以做到这一点。我不会复制粘贴,只是给你类似问题的链接:

你能在 Java 中获得基本的 GC 统计信息吗?

我相信,你会想到如何分析这个统计数据,并决定 GC 何时持续活跃。

因为这个问题包含一些应用 GC 统计的新想法,我不认为它是重复的。

于 2013-01-17T18:36:03.497 回答