为什么选择OOM?第一个gc为什么终身制:8192K->8961K(10240K)?



我的代码:

public class TestJVmRiZHI{   
/**
jdk 1.8
-XX:+UseSerialGC
-verbose:gc
-Xms20M
-Xmx20m
-Xmn10M
-XX:+PrintGCDetails
-XX:SurvivorRatio=8
* @param args
*/     
private  static final int _1mb = 1024 * 1024;
public static void main(String[] args) {
Byte[] allocation1 = new Byte[2*_1mb];
Byte[] allocation2 = new Byte[2*_1mb];
Byte[] allocation3 = new Byte[2*_1mb];
Byte[] allocation4 = new Byte[4*_1mb];
}
}

结果:

线程"main"中的异常 java.lang.OutOfMemoryError: Java 堆空间 在控制器。TestJVmRiZHI.main(TestJVmRiZHI.java:24(

[GC(分配失败([定义新:2540K->770K(9216K(,0.0034872秒]

[任期:8192K->8961K(10240K(,0.0071963秒] 10732K->8961K(19456K(,

[元空间:3385K->3385K(1056768K(],0.0107478秒] [次数:用户=0.01 系统=0.00,真实=0.01秒]

[完整 GC(分配失败([任期:8961K->8943K(10240K(,0.0073261 秒] 8961K->8943K(19456K(,[元空间:3385K->3385K(1056768K(],0.0073536 秒] [次数:用户=0.02 系统=0.00,实际=0.01 秒]

堆 def 新一代总计 9216K,已使用 410K [0x00000000fec00000、0x00000000ff600000、0x00000000ff600000(

伊甸空间 8192K,已使用 5% [0x00000000fec00000、0x00000000fec66800、0x00000000ff400000(

从空间 1024K,使用 0% [0x00000000ff500000、0x00000000ff500000、0x00000000ff600000(

到空间 1024K,使用 0% [0x00000000ff400000、0x00000000ff400000、0x00000000ff500000(

终身世代总计10240K,使用8943K [0x00000000ff600000,0x0000000100000000,0x0000000100000000(

空间 10240K,87% 已使用 [0x00000000ff600000、0x00000000ffebbd38、0x00000000ffebbe00、0x0000000100000000(

元空间已用3429K,容量4494K,承诺4864K,预留1056768K

类空间已用 382K,容量 386K,承诺 512K,预留1048576

Byte[]是对象引用的数组。

对象引用通常为 4 个字节。在堆超过 32 GB 的 64 位计算机上,对象引用为 8 个字节。

因此,假设 4 个字节,2 * 1024 * 1024 * 4 =8 MB。

所以:

allocation1:  8 MB
allocation2:  8 MB
allocation3:  8 MB
allocation4: 16 MB
=====
total: 40 MB

只有-Xmx20m,您的内存就会耗尽。

您可能打算让new Byte[2*_1mb]分配 2 MB,因此将Byte更改为byte,因此数组是基元byte值数组,而不是对象引用数组。

最新更新