【问题标题】:java full gc taking too longjava full gc耗时太长
【发布时间】:2013-05-16 15:35:41
【问题描述】:

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

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

** 更新 ** 我使用了 -XX:+UseConcMarkSweepGC 并且它有所改善,但在非常忙碌的时候我仍然断开连接。所以我将堆分配增加到 3GB 以帮助度过忙碌的时刻,现在它似乎运行得很好,但只有 1 天没有断开连接。也许如果我有时间,我会尝试减少产生的垃圾量,我相信这也会有所帮助。谢谢大家的建议。

【问题讨论】:

  • 你能改变连接的超时时间吗?
  • 将堆大小增加到 4GB 并观察断开模式和 Full GC 时间段。
  • 不幸的是,更改断开连接阈值不是一种选择
  • 我在 Java 服务器应用程序中看到的一件事是每次网络读取和复制都使用一个新对象。尝试更改为使用单字节数组分配进行读取并将字节从那里复制到其他持久字节数组。当然,我对 Java 最不满意的地方之一是大多数人使用代码库,这使得实际上无法进行这些更改,因为它被埋得太深了。

标签: java performance garbage-collection


【解决方案1】:

调用 Runtime.getRuntime().gc() - 当手动触发垃圾收集时,它要么什么都不做,要么进行一次完整的垃圾收集。您希望发生增量 GC。

您是否尝试过使用 jdk 安装中的服务器 jvm?它更改了一堆默认配置设置(包括垃圾收集)并且很容易尝试 - 只需将 -server 添加到您的 java 命令中。

java -server

产生的所有垃圾是什么?你能减少它的产生吗?在可能的情况下,尝试使用 valueOf 方法。通过使用更少的内存,您可以节省 gc 和内存分配的时间。

【讨论】:

    【解决方案2】:

    调整 Full GC 并不容易。一个更好的方法是产生更少的垃圾。产生更少的垃圾可以减少收集的压力,将对象传递到收集起来更昂贵的永久空间。

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

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

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

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

    【讨论】:

    • 我同意减少垃圾。此外,如果您将所有引用保留在函数内,则通过转义分析,它们将在函数退出时被收集。或者他们应该这样做。
    • @ZanLynx 是的,他们应该这样做,但我不认为他们会这样做。 ;) 事实上,如果你能找到这样的例子,请告诉我。逃逸分析将对象放在堆栈而不是堆上,因此它不会被这样收集。
    【解决方案3】:

    Full GC 可能需要很长时间才能完成,而且调整起来并不容易。

    一种(轻松)调优的方法是增加堆空间——一般来说,堆空间加倍可以使两次 GC 之间的间隔加倍,但会使 GC 消耗的时间加倍。如果你运行的程序有非常清晰的使用模式,或许你可以考虑增加堆空间,让间隔变大,保证有一些空闲时间来尝试让系统执行一次GC。另一方面,按照这个逻辑,如果堆很小,一个完整的垃圾回收将在瞬间完成,但这似乎带来的麻烦多于帮助。

    另外,-XX:+UseConcMarkSweepGC 可能会有所帮助,因为它会尝试同时执行 GC 操作(不会停止您的程序;请参阅 here)。

    Here's Til Gene(Azul 系统的 CTO,高性能 JVM 的制造商,并发布了几个 GC 算法)关于 JVM 中的 GC 的精彩演讲。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多