G1 里多大的对象算「巨型」?它为什么浪费空间?没有引用之后要等并发周期才能回收吗?这篇用日志里的 Humongous Allocation 作为信号,逐个字节数地逼近阈值。
-Xmx64m → Heap Region Size 1M -Xmx256m → Heap Region Size 1M -Xmx1g → Heap Region Size 1M -Xmx4g → Heap Region Size 2M -Xmx16g → Heap Region Size 8M -Xmx1g -XX:G1HeapRegionSize=1m → Heap Region Size 1M -Xmx1g -XX:G1HeapRegionSize=2m → Heap Region Size 2M -Xmx1g -XX:G1HeapRegionSize=4m → Heap Region Size 4M -Xmx1g -XX:G1HeapRegionSize=32m → Heap Region Size 32M G1HeapRegionSize=3m(不是 2 的幂)→ 4M
区域 1m(阈值猜测 = 区域的一半 = 524288 字节);每个大小单独起一个 JVM,堆占用门槛调到 1%,保持引用地分配这种大小的 byte[] 直到共约 24 MB(数组对象总大小 = 下面的值,含 16 字节头):
总大小 262144 字节( 25.00% 区域)→ 没有触发(普通对象)
总大小 409600 字节( 39.06% 区域)→ 没有触发(普通对象)
总大小 524224 字节( 49.99% 区域)→ 没有触发(普通对象)
总大小 524280 字节( 50.00% 区域)→ 没有触发(普通对象)
总大小 524288 字节( 50.00% 区域)→ 没有触发(普通对象)
总大小 524296 字节( 50.00% 区域)→ G1 Humongous Allocation 触发了并发周期(巨型对象)
总大小 524352 字节( 50.01% 区域)→ G1 Humongous Allocation 触发了并发周期(巨型对象)
总大小 540672 字节( 51.56% 区域)→ G1 Humongous Allocation 触发了并发周期(巨型对象)
总大小 614400 字节( 58.59% 区域)→ G1 Humongous Allocation 触发了并发周期(巨型对象)
总大小 1048576 字节(100.00% 区域)→ G1 Humongous Allocation 触发了并发周期(巨型对象) 区域 4m(阈值猜测 = 区域的一半 = 2097152 字节);每个大小单独起一个 JVM,堆占用门槛调到 1%,保持引用地分配这种大小的 byte[] 直到共约 24 MB(数组对象总大小 = 下面的值,含 16 字节头):
总大小 614400 字节( 14.65% 区域)→ 没有触发(普通对象)
总大小 1048576 字节( 25.00% 区域)→ 没有触发(普通对象)
总大小 2097088 字节( 50.00% 区域)→ 没有触发(普通对象)
总大小 2097144 字节( 50.00% 区域)→ 没有触发(普通对象)
总大小 2097152 字节( 50.00% 区域)→ 没有触发(普通对象)
总大小 2097160 字节( 50.00% 区域)→ G1 Humongous Allocation 触发了并发周期(巨型对象)
总大小 2097216 字节( 50.00% 区域)→ G1 Humongous Allocation 触发了并发周期(巨型对象)
总大小 2560000 字节( 61.04% 区域)→ G1 Humongous Allocation 触发了并发周期(巨型对象)
总大小 4194304 字节(100.00% 区域)→ G1 Humongous Allocation 触发了并发周期(巨型对象) 100 个 450 KB 数组:有效数据 43.9 MB;堆占用增量 47.9 MB(109%)
100 个 1126 KB 数组:有效数据 110.0 MB;堆占用增量 200.0 MB(182%) 共 7 次暂停(40 个 3 MB 数组共约 120 MB,堆 64 MB);前 4 条:
GC(0) Pause Young (Concurrent Start) (G1 Humongous Allocation) 26M->5M(64M) 0.344ms
GC(2) Pause Young (Concurrent Start) (G1 Humongous Allocation) 25M->5M(64M) 0.182ms
GC(4) Pause Young (Concurrent Start) (G1 Humongous Allocation) 25M->5M(64M) 0.228ms
GC(6) Pause Young (Concurrent Start) (G1 Humongous Allocation) 25M->5M(64M) 0.210ms
暂停类型汇总: ['Young(Concurrent Start,G1 Humongous Allocation)']
没有 Full GC: True ;退出码 0
gc+humongous 日志样例:
GC(0) Humongous region 0 (object size 3145744 @ 0x0000000121800000) remset 0 code roots 0 marked 0 reclaim candidate 1 type array 1
GC(0) Humongous region 8 (object size 3145744 @ 0x0000000122000000) remset 0 code roots 0 marked 0 reclaim candidate 1 type array 1
GC(0) Humongous region 12 (object size 3145744 @ 0x0000000122400000) remset 0 code roots 0 marked 0 reclaim candidate 1 type array 1
GC(0) Humongous region 4 (object size 3145744 @ 0x0000000121c00000) remset 0 code roots 0 marked 0 reclaim candidate 1 type array 1