100%全伊甸园空间,使用Survivor空间的0% - 垃圾收集没有做(100% full Ede

2019-06-26 01:38发布

我曾经遇到过一个相当混乱GC情况:当伊甸园空间是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

Answer 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

如果生存空间太小,复制集合直接溢出到年老代。

对于任何澄清,指该链接。

编辑:

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

计算:

    y/t=1/3

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

 t=tenured
 y=young
 h=heap


Answer 2:

线程本地缓冲区距离Eden空间分配。 只要一个缓冲区分配,在伊甸园空间的自由空间减少十足。 这可能意味着你有很多TLAB这几乎是空的,但伊甸园空间显得完整。 当没有在伊甸园空间足够空间的GC被触发。

如果关闭TLAB -XX:-UseTLAB这会降低性能,但你会得到的空间的使用多少准确核算。



Answer 3:

只是一个想法,但我看到老根还满。 难道是想清理伊甸园的GC,而不是忙于运行完整的GC试图清理旧世代以避免OOM。



Answer 4:

SurvivorRatio计算:

如果SurvivorRatio = 6然后(一张SurvivorSpace:伊甸)的比=(1:6)。
所以两个Survivor将采取(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.

Nathamticlly

的S - 幸存者
Ë - 伊甸园
Ÿ - 年轻一代

if SurvivorRatio=6
then S / E = 1/6
         E = 6S

2S + E = Y
2S + 6S = Y
S = Y / 8

影响

如果在较小的空间增加更多的价值SurvivorRatio结果幸存者将结果,推伊甸空间对象直接进入旧/终身根。 通过轻微的GC中滤出生存空间拍摄活动对象小的机会。 此外,这可能增加饱GC的没有。

如果这降低到更小的值将导致较小的伊甸园空间将频繁未成年GC。

要知道,采取轻微GC的时候会更多,特别是如果我们使用串行GC算法,其中只有一个线程将被用于GC,虽然你的机器是多核机器。

还需要注意的是-XX:+UseAdaptiveSizePolicy将在运行时间确定JVM自身SurvivorRatio,但它始终是最好通过尝试多个负载运行它手动根据您的应用程序不在话下。



文章来源: 100% full Eden space, 0% used Survivor space - Garbage collection not done