首页 > 解决方案 > Major GC 性能下降

问题描述

我们的应用程序经常中断,基本上堆会随着时间的推移而增长,以至于 GC 需要大量的 CPU 时间并执行几分钟,从而大大降低了应用程序的性能。该应用程序位于带有 tomcat 服务器的 JSF 中。

与此同时,我们:

随着堆大小的增加,GC 不会执行很长时间,但仍会占用大量 CPU 并冻结应用程序。 长钉

所以问题是:

更新: 我将 JSF 从 2.2 更改为 2.3,因为一些堆转储指出 JSF 正在使用大量内存。那没有成功,昨天我们又停电了,但这一次有点不同(从我的角度来看)。同样这一次,我们不得不重置tomcat,因为应用程序在一段时间后不再工作了

在此处输入图像描述

在这种情况下,垃圾收集器在de old gen heap未满时运行,而新生代GC一直在运行。¿ 这可能是什么原因?

标签: javaperformancetomcatmemorygarbage-collection

解决方案


正如评论中所说,应用程序的行为看起来并不合理。您的代码不断分配导致堆空间填满的对象,从而导致 GC 运行。似乎没有内存泄漏,因为 GC 回收了大量空间并且总体使用空间并未持续增加。

一个问题似乎是大量对象在被收集之前被提升为老一代。由于对象的重定位和重新映射(假设您使用的是压缩算法),主要 GC 周期在 CPU 方面的成本更高。

为了减少这种情况,您可以尝试增加年轻代的大小。当您增加整体堆大小但还不够时,就会发生这种情况。理想情况下,您希望在次要 GC 周期中收集大部分对象,因为这实际上是免费的(在收集 Eden 空间中的对象时,GC 不会对它们做任何事情)。您可以使用-XX:NewRatio=or-XX:NewSize=标志来执行此操作。您还可以尝试更改幸存者空间大小,再次增加在使用前收集的对象数量。-XX:SurvivorRatio=(为此使用标志)。

对于监控,我发现 Flight Recorder 和 Mission Control 非常有用,因为您可以深入了解分配了多少特定类型的对象的详细信息。连接到正在运行的 JVM 或进行转储以供以后分析也很容易。


推荐阅读