JVM使用大量GC消耗100%的CPU

时间:2014-11-18 20:30:16

标签: java garbage-collection jvm

运行几天后,我的JVM的CPU负载大约为100%,大约有10%的GC(截图)。

内存消耗接近最大值(约6 GB)。 在那个州,tomcat非常缓慢。

JVM CPU usage

3 个答案:

答案 0 :(得分:4)

由于评论过多,我会写下来并回答:

查看您的图表,似乎是使用CPU进行非GC任务,峰值“GC活动”似乎保持在10%以内。

因此,在第一印象中,您的任务似乎只是CPU绑定的,所以如果这是意外的,您可能应该对您的Java应用程序进行一些CPU分析,看看是否有弹出的东西。

除此之外,根据评论,我怀疑物理内存填满可能会导致文件缓存和内存映射事件,导致页面错误增加,迫使CPU等待IO。

从4GB堆中手动GC上释放500MB并不是那么多,大多数GC尝试将暂停时间保持在低位作为其主要目标,将GC中花费的总时间保留在某些限制内作为次要目标且仅当其他目标得到满足时,他们会尝试将内存占用减少为第三目标。

在推荐进一步的步骤之前,您应该收集更多统计信息/提供更多信息,因为很难从您的描述中辨别出您的实际问题。

  • 监控页面错误
  • 确定您的设置中使用了哪种GC算法以及如何调整它们(-XX:+ PrintFlagsFinal)
  • 记录GC活动 - 我怀疑它很少使用较小的GC,从而占用其暂停时间或CPU负载目标
  • 执行应用程序的分配概要分析(任何产生过多垃圾的东西?)

您还必须小心区分由于Java堆达到其大小限制而导致的问题与操作系统耗尽其物理内存导致的问题。

TL; DR:问题不明确,需要更多信息。

或者,如果你很懒/能负担得起,只需插入更多内存/从机器上删除其他服务,看看问题是否消失。

答案 1 :(得分:2)

我学会了对GC问题进行检查:

  • 为JVM提供足够的内存,例如-Xmx2G
  • 如果内存不足并且主机上没有更多RAM可用,请分析HEAP转储(例如,通过jvisualvm)。
  • 启用Concurrent Marc和Sweep: -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
  • 检查垃圾收集日志:-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log

我的解决方案:

但我最终通过调整缓存大小来解决这个问题。 缓存大小很大,因此内存很少。

答案 2 :(得分:1)

如果你想保持服务器的内存空闲,你可以简单地尝试使用vm-parameter

-Xmx2G //or any different value

这可确保您的程序永远不会超过2 GB的Ram。但请注意,如果高工作负载的情况,服务器可能会获得OutOfMemoryError。

由于旧一代(完整)GC可能会阻止整个服务器工作几秒钟,因此java会尝试避免完全垃圾收集。

Ram-Limitation可以更容易地触发全代GC(甚至可以支持Young-Generation GC收集更多物体)。

从我的(更多猜测而不是实际知道)意见:我不认为另一种算法可以帮助这么多。