这描述的是开箱即用的行为G1垃圾收集器 https://www.oracle.com/technical-resources/articles/java/g1gc.html它通常默认为 1MB“区域”,并成为 Java 9 中的 JVM 默认值。在启用其他 GC 的情况下运行会给出不同的数字。
任何超过区域大小一半的对象都被考虑
“巨大的”...对于只比一个稍大的物体
堆区域大小的倍数,此未使用的空间可能会导致堆
变得支离破碎。
I ran java -Xmx300M -XX:+PrintGCDetails
它显示堆已被巨大的区域耗尽:
[0.202s][info ][gc,heap ] GC(51) Old regions: 1->1
[0.202s][info ][gc,heap ] GC(51) Archive regions: 2->2
[0.202s][info ][gc,heap ] GC(51) Humongous regions: 296->296
[0.202s][info ][gc ] GC(51) Pause Full (G1 Humongous Allocation) 297M->297M(300M) 1.935ms
[0.202s][info ][gc,cpu ] GC(51) User=0.01s Sys=0.00s Real=0.00s
...
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
我们想要 1MiBbyte[]
“小于 G1 区域大小的一半”,因此添加-XX:G1HeapRegionSize=4M
给出一个函数式应用:
[0.161s][info ][gc,heap ] GC(19) Humongous regions: 0->0
[0.161s][info ][gc,metaspace ] GC(19) Metaspace: 320K->320K(1056768K)
[0.161s][info ][gc ] GC(19) Pause Full (System.gc()) 274M->204M(300M) 9.702ms
remaining free: 100
used: 209
expected usage: 200
G1的深入概述:https://www.oracle.com/technical-resources/articles/java/g1gc.html https://www.oracle.com/technical-resources/articles/java/g1gc.html
G1粉碎细节:https://docs.oracle.com/en/java/javase/13/gctuning/garbage-first-garbage-collector-tuning.html#GUID-2428DA90-B93D-48E6-B336-A849ADF1C552 https://docs.oracle.com/en/java/javase/13/gctuning/garbage-first-garbage-collector-tuning.html#GUID-2428DA90-B93D-48E6-B336-A849ADF1C552