我曾经遇到过一个相当混乱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
当我在你的堆配置看,我发现,
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
线程本地缓冲区距离Eden空间分配。 只要一个缓冲区分配,在伊甸园空间的自由空间减少十足。 这可能意味着你有很多TLAB这几乎是空的,但伊甸园空间显得完整。 当没有在伊甸园空间足够空间的GC被触发。
如果关闭TLAB -XX:-UseTLAB
这会降低性能,但你会得到的空间的使用多少准确核算。
只是一个想法,但我看到老根还满。 难道是想清理伊甸园的GC,而不是忙于运行完整的GC试图清理旧世代以避免OOM。
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,但它始终是最好通过尝试多个负载运行它手动根据您的应用程序不在话下。