我检查了 Harmony JVM 中的对象布局(我想 JVM 的其他实现类似)。java中的每个Object都有一个对象头,其中包含JVM的重要信息。最重要的是对对象类的引用(一个词)。此外,GC 使用了一些标志来管理同步,即锁定字(因为每个对象都可以同步)占用另一个字(使用部分字对性能不利)。所以这是 2 个字,在 32 位系统上是 8 个字节,在 64 位系统上是 16 个字节。数组还需要一个 int 字段来表示数组长度,即另外4 个字节,可能是8 个字节在 64 位系统上。所以对于每个数组,在 32 位机器上我们有 12 个额外的字节,在 64 位机器上可能是 24 个字节。
在您的程序中,您有 6 个数组数组。100480507 一维阵列。所以额外的内存消耗大约是 1.2 + 0.6 GB,这是一个非常大的连续内存块。开销约为 200%。
当我们将代码更改为:
public class MemTest {
public static void main(String[] args) {
int NUM_RECORDS = 100480507;
byte[] completeArray = new byte[NUM_RECORDS * 6];
System.out.println("Array created");
}
}
我们只创建 1 个数组,因此开销非常小。总共约0.6GB。
当代码更改为:
public class MemTest {
public static void main(String[] args) {
int NUM_RECORDS = 100480507;
byte[][] completeArray = new byte[NUM_RECORDS][6];
System.out.println("Array created");
}
}
我们总共有 7 个数组。该程序将立即结束。
以您的代码样式创建另一个 0.6GB 内存,但将元素类型从 int 更改为 long:
public class MemTest {
public static void main(String[] args) {
int NUM_RECORDS = 12560063;
long[][] completeArray = new long[NUM_RECORDS][6];
System.out.println("Array created");
}
}
该程序也可以立即结束。开销约为 150M/600M = 25%。