如果我通过java -Xmx12m OOM
执行下面的课程,怎么会失败并显示java.lang.OutOfMemoryError Java heap space
消息。但如果它适用于java -Xmx13m OOM
。
class OOM {
static final int SIZE=2*1024*1024;
public static void main(String[] a) {
int[] i = new int[SIZE];
}
}
我认为int
是4个字节所以2 * 1024 * 1024 * 4 = 8,388,608bytes。它还低于12,对吧?那么-Xmx12m
怎么会失败但-Xmx13m
有效?
答案 0 :(得分:4)
-Xmx
选项设置总(最大)堆大小。但是,Java堆通常由2个(或更多)空格 1 组成,并且Java对象必须适合单个空间。
当你将堆设置为12mb时,这两个空间都不够大 2 来保存~8mb的单个对象。当您将总堆大小增加到13mb时,其中一个空间足够大。
1 - “new”或“eden”空间是通常分配新对象的位置。 “旧”或“终身”空间是物体在经过一定数量的GC循环后仍然存在的地方。但是,真正大的对象(如你的)可以直接分配到“旧”空间。 (注意:这是一个简化......)
2 - 可以调整新空间的相对大小,但这会产生其他后果。例如,如果过多地减小新空间的大小,则可能会增加“完整”GC的百分比......这会影响吞吐量和GC暂停。
答案 1 :(得分:2)
我同意Stephan C.
我想通过Alexey Zhebel提供此blog的更多信息
下图详细介绍了java内存架构。
堆内存(-Xmx)= Youn gen(Eden space)+ Survivor Space + Olde gen(Tenured space)
您的总堆内存似乎超过12米但不超过13米。