日常GC同时运行

时间:2011-09-30 02:39:33

标签: jboss garbage-collection

在我的服务器每天凌晨3:00运行GC并且Heapspace正在填充闪存。

导致网站中断。有什么输入?

以下是我的JVM设置。我正在使用JBOSS服务器。

-Dprogram.name = run.sh -server -Xms1524m -Xmx1524m -Dsun.rmi.dgc.client.gcInterval = 3600000 -Dsun.rmi.dgc.server.gcInterval = 3600000 -XX:NewSize = 512m -XX: MaxNewSize = 512m -Djava.net.preferIPv4Stack = true -XX:MaxPermSize = 512m -XX:+ UseConcMarkSweepGC -XX:+ CMSClassUnloadingEnabled -Djavax.net.ssl.trustStorePassword = changeit -Dcom.sun.management.jmxremote.port = 8888 - Djava.rmi.server.hostname = 192.168.100.140 -Dcom.sun.management.jmxremote.ssl = false -Dcom.sun.management.jmxremote

任何建议真有帮助..

1 个答案:

答案 0 :(得分:4)

(结果有点长;最后有一个实际的修复建议。)

非常简单,使用-XX时垃圾收集:+ UseConcMarkSweepGC的工作原理如下:

所有对象都分配在所谓的年轻一代中。这通常是几百个meg到一个gig的大小,具体取决于VM设置,CPU数量和总堆大小。年轻一代被收集在一个停止世界的暂停,然后是并行(多CPU)压缩(移动物体)集合。年轻一代的大小使得这种停顿相当大。

当对象幸存下来(仍然可以访问)年轻时,他们会升级到“老一代”(老一代)。

老一代是-XX:+ UseConcMarkSweepGC开始。在默认模式下(没有-XX:+ UseConcMarkSweepGC)当旧一代变满时,整个堆被收集并压缩(四处移动,消除碎片)在世界各地的副本。该暂停通常比年轻暂停更长,因为涉及整个堆,这更大。

使用CMS(-XX:+ UseConcMarkSweepGC)来压缩旧代的工作大多是并发的(意味着,在后台运行,应用程序暂停)。这项工作也压缩;它的工作方式更像malloc()/ free(),并且你会受到碎片化。

CMS的主要好处是,当事情运作良好时,你可以避免长时间的停顿时间与堆的大小成线性关系,因为主要工作是锥形并发(有一些停止世界的步骤,但他们应该通常是短暂的。)

两个主要缺点是:

  • 因为没有压缩旧版本,所以你会受到破碎。
  • 如果在旧版填充之前没有完成并发收集周期,或者碎片阻止分配,则整个堆的最终完整集合并行,因为它是默认的集电极。我......只使用一个CPU。这意味着当/如果你点击完整的垃圾收集时,暂停将更长,而不是默认的收集器。

现在......你的日志。 “并发模式故障”旨在表明并发标记/扫描工作没有及时完成另一个需要将幸存物体提升到老一代的年轻GC。 “促销失败”的意思是,在从年轻人到老一代的推广过程中,由于碎片化,一个对象无法在旧版本中进行分配。

除非您在JVM中遇到真正的错误,否则堆使用率的突然增加几乎可以肯定来自您的应用程序,JBoss或作用于您的应用程序的某个外部实体。所以我无法真正帮助你。然而,可能发生的事情是两件事的结合:

  1. 活动高峰导致堆使用量增加太快,无法及时完成并发收集。
  2. 老一代太过分散,导致问题,特别是当老一代几乎已经满了。
  3. 我现在还应该指出,CMS的默认行为是尽可能地推迟并发集合(但是长)是出于性能原因。发生的越晚,集合就越有效(就CPU使用而言)。然而,权衡的是你增加了没有及时完成的​​风险(这将再次触发完整的GC和长时间停顿)。它也应该(我没有在这里进行实证检验,但这是合理的)导致分裂成为一个更大的问题;基本上,当一个对象被提升时,更完整的老一代,对象的推广可能会加剧对碎片问题的影响(这里的细节太长了)。

    在你的情况下,我会做两件事:

    1. 继续弄清楚导致活动的原因。我想说它不太可能是GC / JVM错误。
    2. 重新配置JVM以更早地触发并发收集周期,以避免堆每一个变得如此充满,以至于碎片成为一个特别重要的问题,并且即使在突然出现活动高峰时也给它更多时间来及时完成。 / LI>

      您可以轻松完成(2)使用JVM选项

      • -XX:CMSInitiatingOccupancyFraction=75
      • -XX:+UseCMSInitiatingOccupancyOnly

      为了明确强制JVM在特定的堆使用级别启动CMS循环(在此示例中为75% - 您可能需要更改它;百分比越低,它将越早启动)。

      请注意,根据您的实时大小(实际上是活动的和可访问的字节数),强制较早的CMS周期可能还需要增加堆大小以避免CMS不断运行(不是好好利用CPU)。