【问题标题】:100% full Eden space, 0% used Survivor space - Garbage collection not done100% 完整的伊甸园空间,0% 使用的幸存者空间 - 垃圾收集未完成
【发布时间】:2012-07-05 07:29:45
【问题描述】:

我遇到了一个相当令人困惑的 GC 案例:当 Eden 空间 100% 满时,使用了 0% 的幸存者空间。当伊甸园满了,应该触发垃圾回收吧?

是否存在阻止 GC 守护程序运行的情况?像 100% 的 CPU?

我们正在使用jdk-1.7

可能是什么原因?以下是 jmap 输出。

我们还尝试使用jmap -histo -F 捕获更详细的内存使用情况,但随后 CPU 使用率降至 0%,java 进程无法访问。

using thread-local object allocation.
Parallel GC with 18 thread(s)

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 12884901888 (12288.0MB)
   NewSize          = 1310720 (1.25MB)
   MaxNewSize       = 17592186044415 MB
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 85983232 (82.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 4265738240 (4068.125MB)
   used     = 4265738240 (4068.125MB)
   free     = 0 (0.0MB)
   100.0% used
From Space:
   capacity = 14352384 (13.6875MB)
   used     = 0 (0.0MB)
   free     = 14352384 (13.6875MB)
   0.0% used
To Space:
   capacity = 14680064 (14.0MB)
   used     = 0 (0.0MB)
   free     = 14680064 (14.0MB)
   0.0% used
PS Old Generation
   capacity = 8589934592 (8192.0MB)
   used     = 8589931920 (8191.997451782227MB)
   free     = 2672 (0.0025482177734375MB)
   99.99996889382601% used
PS Perm Generation
   capacity = 41353216 (39.4375MB)
   used     = 41079056 (39.17604064941406MB)
   free     = 274160 (0.2614593505859375MB)
   99.33702858805468% used

【问题讨论】:

  • 你监控过线程转储吗?有什么鱼腥味吗?
  • 我们也尝试使用 jmap -histo -F 捕获更详细的内存使用情况,但随后 CPU 使用率降至 0%,java 进程无法访问。
  • 想推荐你在这种情况下使用visualvm。
  • 您的 perm-gen 也已满 - 使用 openJDK6 我确实看到这曾经导致非常奇怪的行为,但没有引发 PermGenSpace 错误。尝试提高它。

标签: java garbage-collection


【解决方案1】:

当我看到你的堆配置时,我发现

MaxNewSize = 17592186044415 MB 不正确,但必须以字节为单位。

我看到几乎所有的世代都在同一时间,Collector 正试图收集这两个世代,所以它们互相阻塞。

我建议请使用以下参数调整内存。

-XX:NewRatio=3 - the young generation will occupy 1/4 the overall heap
-XX:NewSize - Calculated automatically if you specify -XX:NewRatio
-XX:MaxNewSize - The largest size the young generation can grow to (unlimited if this value is not specified at command line)

我还建议使用一些幸存者空间,当对象从eden 复制到“终身”代时,它会为收集器提供时间。

-XX:SurvivorRatio=6 - each survivor space will be 1/8 the young generation

如果幸存者空间太小,复制集合会直接溢出到终身代。

有关任何说明,请参阅this 链接。

编辑:

-XX:NewRatio=3 - 年轻代将占据整个堆的 1/4

计算:

    y/t=1/3

    y+t=h
    y+3y=h
    y=h/4

 t=tenured
 y=young
 h=heap

【讨论】:

  • MaxNewSize 的 jmap 输出错误:bugs.sun.com/bugdatabase/…
  • 如果我设置 -XX:NewRatio=3,年轻代将占据整个堆的 3/4,而不是 1/4,对吗?
  • @kuloglan 否 如果我们设置 -XX:NewRatio=3 表示年轻代和老生代的比例为 1:3 即部分年轻代将是 1/4
【解决方案2】:

线程本地缓冲区是从伊甸园空间分配的。一旦分配了缓冲区,伊甸园空间中的空闲空间就会全部减少。这可能意味着您有许多几乎是空的 TLAB,但伊甸园空间似乎已满。当 eden 空间中没有足够的可用空间时触发 GC。

如果您关闭 TLAB -XX:-UseTLAB,这会降低性能,但您将获得更准确的空间使用情况。

【讨论】:

    【解决方案3】:

    SurvivorRatio 计算:

    如果 SurvivorRatio=6,那么 (One SurvivorSpace : Eden) 的比率 = (1:6)。
    所以两个幸存者会拿(2部分),伊甸园有6部分。所以总共8个部分。
    所以如果我有 40 MB 的年轻一代,伊甸园是 (6/8 * 40)MB,一个幸存者将有 (1/8 * 40)MB。

    如果 SurvivorRatio=7。那么总部分是(7 + 1 + 1 = 9)。 伊甸园为 (7/9 * 40)MB,幸存者将拥有 (1/9 * 40)MB

    理论上

        The SurvivorRatio parameter controls the size of the two survivor spaces.
     For example, -XX:SurvivorRatio=6 sets the ratio between each survivor space 
    and eden to be 1:6, each survivor space will be one eighth of the young 
    generation.
    

    数学

    S - 幸存者
    E - 伊甸园
    Y - 年轻代

    if SurvivorRatio=6
    then S / E = 1/6
             E = 6S
    
    2S + E = Y
    2S + 6S = Y
    S = Y / 8
    

    效果

    如果将 SurvivorRatio 值增加到更大的值会导致 Survivor 的空间更小,则会将 eden 空间对象直接推入 old/tenured gen。通过次要 GC 过滤出幸存者空间中拍摄的活动对象的机会较小。这也可能会增加完整 GC 的数量。

    如果将此值降低到更低的值会导致更小的 eden 空间,则会导致次要 GC 频繁。

    知道 Minor GC 所花费的时间会更多,特别是如果我们使用串行 GC 算法,其中仅使用单线程进行 GC,尽管您的机器是多核机器。

    还请注意-XX:+UseAdaptiveSizePolicy 将在运行时确定 JVM 自己的 SurvivorRatio,但最好根据您的应用程序通过尝试多次加载运行手动提及它。

    【讨论】:

      【解决方案4】:

      只是一个想法,但我看到老一代也满了。会不会是 GC 而不是试图清理 Eden 正忙于运行 full GC 试图清理老年代以避免 OOM。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-03
        • 2012-08-11
        • 2018-05-10
        • 1970-01-01
        • 2016-02-05
        • 2013-10-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多