java全gc花了太长时间

JCB*_*JCB 4 java performance garbage-collection

我有一个Java客户端,它从服务器消耗大量数据.如果客户端无法以足够快的速率跟上数据流,则服务器会断开套接字连接.我的客户每天断开连接几次.我运行jconsole来查看内存使用情况,堆空间图看起来像一个相当明确的锯齿模式,在大约0.5GB和1.8GB之间振荡(分配2GB的堆空间).但每次断开连接都是在完整的GC期间(但不是每个完整的GC).我看到完整的GC平均需要1秒多一点.根据一天中的时间,完整的GC会在繁忙时每5分钟发生一次,或者在慢速期间可以在完整的GC之间进行30分钟.

我怀疑如果我可以减少完整的GC时间,客户端将能够更好地跟上传入的数据,但我没有太多的GC调整经验.有没有人知道这是否是一个好主意,以及如何做到这一点?或者是否有其他可能也有效的想法?

**更新**我使用-XX:+ UseConcMarkSweepGC并且它有所改进,但我仍然在非常繁忙的时刻断开连接.因此,我将堆分配增加到3GB,以帮助度过忙碌的时刻,现在看起来好像很好,但它只有1天没有断开连接.也许如果我得到一些时间,我会经历并尝试减少创建的垃圾量,我相信也会有所帮助.感谢所有的建议.

zw3*_*324 12

完整的GC可能需要很长时间才能完成,并且不容易调整.

(轻松)调整它的一种方法是增加堆空间 - 一般来说,堆空间的两倍可以使两个GC之间的间隔加倍,但会使GC消耗的时间加倍.如果您运行的程序具有非常明确的使用模式,也许您可​​以考虑增加堆空间以使间隔如此之大,以至于您可以保证有一些空闲时间来尝试使系统执行GC.另一方面,遵循这个逻辑,如果堆很小,一个完整的垃圾收集将立即完成,但这似乎比帮助更多的麻烦.

此外,-XX:+UseConcMarkSweepGC可能有帮助,因为它将尝试同时执行G​​C操作(不停止您的程序;请参阅此处).

以下是 Til Gene(Azul系统的CTO,高性能JVM的制造商,并发布了几个GC算法)一个非常好的演讲,关于JVM中的GC.


Pet*_*rey 5

调离 Full GC 并不容易。一个更好的方法是产生更少的垃圾。产生更少的垃圾减少了收集的压力,以便将对象传递到年老空间中,在那里收集它们的成本更高。

我建议你使用内存分析器来

  • 减少垃圾产生量。在许多应用中,这可以相对容易地减少 2 - 10 倍。
  • 减少您正在创建的对象的大小,例如使用原始和较小的数据类型,如 double 而不是 BigDecimal。
  • 回收可变对象而不是丢弃它们。
  • 如果可以的话,在客户端上保留更少的数据。

通过减少您创建的垃圾数量,对象更有可能在伊甸园或幸存者空间中消亡,这意味着您拥有的完整集合要少得多,也可以更短。

不要认为这是理所当然的,你必须忍受大量的收藏,在极端情况下你几乎可以完全避免它http://vanillajava.blogspot.ro/2011/06/how-to-avoid-garbage-collection.html