当前位置: 首页 > 知识库问答 >
问题:

垃圾收集有时需要很长时间

宰坚
2023-03-14

在我们的kafka broker设置中,GC平均需要20毫秒,但随机增加到1-2秒。极端情况持续9秒。这种情况的发生频率相当随机。平均每天发生15次。我尝试过使用GCEasy,但没有给出任何见解。我的内存使用率为20%,但进程仍然使用交换,尽管内存可用。感谢您对如何将其最小化的任何意见

JVM选择:

-Xmx3G -Xms1G -server -XX:MetaspaceSize=96m -XX:+UseG1GC -
XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=50 -
XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -
XX:MaxMetaspaceFreeRatio=80

GC日志:

2018-04-15T18:22:26.526+0530: 529212.538: [GC pause (G1 Evacuation Pause) (young), 9.6174677 secs]
       [Parallel Time: 9422.7 ms, GC Workers: 10]
          [GC Worker Start (ms): Min: 529212702.8, Avg: 529212736.2, Max: 529212778.8, Diff: 76.1]
          [Ext Root Scanning (ms): Min: 117.8, Avg: 228.8, Max: 320.4, Diff: 202.5, Sum: 2287.9]
          [Update RS (ms): Min: 83.7, Avg: 134.0, Max: 203.6, Diff: 119.9, Sum: 1339.8]
             [Processed Buffers: Min: 1, Avg: 5.3, Max: 11, Diff: 10, Sum: 53]
          [Scan RS (ms): Min: 390.7, Avg: 449.4, Max: 498.2, Diff: 107.6, Sum: 4493.6]
          [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
          [Object Copy (ms): Min: 8438.7, Avg: 8496.9, Max: 8532.1, Diff: 93.3, Sum: 84969.4]
          [Termination (ms): Min: 0.0, Avg: 18.8, Max: 21.5, Diff: 21.5, Sum: 187.9]
             [Termination Attempts: Min: 1, Avg: 3.8, Max: 9, Diff: 8, Sum: 38]
          [GC Worker Other (ms): Min: 2.5, Avg: 27.3, Max: 91.3, Diff: 88.8, Sum: 273.1]
          [GC Worker Total (ms): Min: 9312.4, Avg: 9355.2, Max: 9388.3, Diff: 75.9, Sum: 93551.7]
          [GC Worker End (ms): Min: 529222091.1, Avg: 529222091.3, Max: 529222091.7, Diff: 0.6]
       [Code Root Fixup: 1.9 ms]
       [Code Root Purge: 0.0 ms]
       [Clear CT: 12.1 ms]
       [Other: 180.8 ms]
          [Choose CSet: 0.0 ms]
          [Ref Proc: 18.0 ms]
          [Ref Enq: 0.0 ms]
          [Redirty Cards: 13.4 ms]
          [Humongous Register: 11.8 ms]
          [Humongous Reclaim: 0.2 ms]
          [Free CSet: 5.1 ms]
       [Eden: 768.0M(128.0M)->0.0B(128.0M) Survivors: 16.0M->16.0M Heap: 1775.9M(3072.0M)->1007.3M(3072.0M)]
     [Times: user=10.00 sys=15.22, real=9.63 secs]

共有1个答案

卞博简
2023-03-14

您的日志显示,每个区域每个gc线程的单独时间很低(以100ms为单位),但整个垃圾收集的总体时间很长,对象复制阶段占用了大部分时间。

[Parallel Time: 9422.7 ms, GC Workers: 10]
          [GC Worker Start (ms): Min: 529212702.8, Avg: 529212736.2, Max: 529212778.8, Diff: 76.1]
          [Ext Root Scanning (ms): Min: 117.8, Avg: 228.8, Max: 320.4, Diff: 202.5, **Sum: 2287.9**]
          [Update RS (ms): Min: 83.7, Avg: 134.0, Max: 203.6, Diff: 119.9, **Sum: 1339.8**]
             [Processed Buffers: Min: 1, Avg: 5.3, Max: 11, Diff: 10, Sum: 53]
          [Scan RS (ms): Min: 390.7, Avg: 449.4, Max: 498.2, Diff: 107.6, **Sum: 4493.6**]
          [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
          **[Object Copy (ms): Min: 8438.7, Avg: 8496.9, Max: 8532.1, Diff: 93.3, Sum: 84969.4]**
          [Termination (ms): Min: 0.0, Avg: 18.8, Max: 21.5, Diff: 21.5, Sum: 187.9]
             [Termination Attempts: Min: 1, Avg: 3.8, Max: 9, Diff: 8, Sum: 38]
          [GC Worker Other (ms): Min: 2.5, Avg: 27.3, Max: 91.3, Diff: 88.8, Sum: 273.1]
          [GC Worker Total (ms): Min: 9312.4, Avg: 9355.2, Max: 9388.3, Diff: 75.9, Sum: 93551.7]
          [GC Worker End (ms): Min: 529222091.1, Avg: 529222091.3, Max: 529222091.7, Diff: 0.6]

这意味着收集的平均时间会变得更高。我认为这种行为没有什么原因,

>

  • XX:G1HeapRegionSize=16M——这个参数的设置应该考虑可用内核的数量、允许的gc线程/工作线程等。最好让JVM为您选择这个值,除非您对此非常确定。

    对象复制阶段是从幸存者空间复制对象到下一个空间的过程。看起来您正在短时间内创建大量新对象。如果可能的话,可以尝试增加堆的大小,尤其是年轻一代的大小。这将减少对象从一个幸存者空间复制到另一个幸存者空间的频率。

    这也可能是因为交换而发生的,但不能从这些日志中确定。禁用交换是值得一试的,因为这是罪魁祸首。

    如果在cpu方面有更多的处理能力,那么尝试增加gc工作线程的数量。

  •  类似资料:
    • 问题内容: 我有一段代码可以在内存中加载很大的图像。所以打电话似乎是合理的事情 在加载图像之前。据我所知,它毫无问题。 昨天,我决定使用一个名为FindBugs的非常有用的软件来扫描您的代码并报告可能导致错误或通常不建议使用的策略的问题。问题是我提到的这段代码得到了报告。描述是这样的: …强迫垃圾收集;除了基准测试代码外,都非常可疑 并继续阐述: 代码显式调用垃圾回收。除了基准测试中的特定用途外,

    • 问题内容: 我不是Java的新手,但是我对垃圾收集只了解一点点。现在,我想通过一些实践经验来改变这种状况。我的目标是在0.3秒以下的延迟,或者在极端情况下0.5也可以。 我有一个带有-Xmx50gb(-Xms50gb)的应用程序,并设置了以下其他GC选项: 但是现在由于垃圾回收,尽管偶尔有足够的可用内存,但我偶尔会在5秒内停顿很长时间。我发现的原因之一: 为什么GCG1仍为此做一个“停止世界”?(

    • Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经有但以后不再拥有 Owner 了。 注意:垃圾收集是 beta 特性,在 Kubernetes 1.4 及以上版本默认启用。 Owner 和 Dependent 一些 Kubernetes 对象是其它一些的 Owner。例如,一个 ReplicaSet 是一组 Pod 的 Owner。具有 Owner 的对象被称为是 Owner

    • 问题内容: 是什么决定了垃圾收集器何时真正收集?它是在一定时间之后还是在一定数量的内存用完之后发生的吗?还是还有其他因素? 问题答案: 它在确定是时候运行时运行。在世代垃圾收集器中,一种常见的策略是在第0代内存分配失败时运行收集器。也就是说,每次你分配一小块内存(大块通常直接放置在“旧”代中)时,系统都会检查gen-0堆中是否有足够的可用空间,如果没有,则运行GC释放空间以使分配成功。然后将旧数据

    • 我试图了解垃圾收集是如何工作的。我很清楚以下几点: 当JVM无法将对象分配给年轻一代时,它将触发小型GC 列表项 当堆满时,JVM将触发完整的GC(两个次要的主要GC)。 但是,年轻一代和老一代中不再引用、符合GC条件但没有触发GC的对象如何(即年轻/老一代堆空间未满,因此没有GC发生) 这是否意味着在GC发生之前,这些对象将保留在年轻/老一代堆空间中? 我的阅读材料 > http://www.c

    • 为了理解可用的JVM垃圾收集算法,我在查看java-available垃圾收集算法链接时感到困惑。 根据我的理解,将会有一些标准的GC算法,不同的JVM供应商实现这些算法来创建垃圾收集器。 现在请帮助我理解下面是算法还是算法的实现: 序列, 平行, CMS, G1, 我认为这些是实现某些特定算法的垃圾收集器类型(我不知道算法的名称)。 此外,我还浏览了在http://www.oracle.com/