我的测试代码:
-Xmx2048m -XX:+UseG1GC -XX:+PrintGCDetails
我在java 8 Heap
garbage-first heap total 2097152K, used 1048100K [0x0000000080000000, 0x0000000080104000, 0x0000000100000000)
region size 1024K, 1 young (1024K), 0 survivors (0K)
Metaspace used 3273K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 358K, capacity 388K, committed 512K, reserved 1048576K
当仅消耗1G时,OutOfMemory失败。
UseConcMarkSweepGC
我看到G1分配的大小是2G,我想JVM正在尝试分配更多并且因OOM而失败。但是,如果内存的一半是免费的,它为什么要分配更多呢?
ffmpeg -i testffm.mp4 -b:v 1M -g 60 -hls_time 2 -hls_list_size 0 -hls_segment_size 500000 exist.m3u8
它工作正常,阵列已完全填满。
答案 0 :(得分:6)
我很确定这会因Humongous Allocations而发生 如果添加此选项
-XX:+ PrintAdaptiveSizePolicy
您将能够看到大多数分配都是1048592字节,它不适合单个G1区域的50%甚至100%(在输出中看到的是1024K = 1048576字节)。我认为这意味着每个阵列至少占据两个区域。由于它是一个巨大的分配,因此不能使用第二区域中的大部分自由空间。这很快导致极端堆碎,从而无法进行进一步的分配。
答案 1 :(得分:1)
同意@yegodm。解决方案是使用-XX:G1HeapRegionSize增加堆区域,以确保先前的Humongous对象不再是Humongous并且将遵循常规分配路径。在此处阅读有关大量对象分配的更多信息1