1 MB 或更大的 Java 字节数组占用两倍的 RAM
在Windows 10 / OpenJDK上运行以下代码11.0.4_x64生成为输出和。这意味着 100 万个元素的 200 字节数组占用大约 200MB RAM。一切都很好。used: 197
expected usage: 200
当我将代码中的字节数组分配从 更改为 (即,更改为 1024*1024 个元素) 时,它将生成为输出和 。这到底是怎么回事?new byte[1000000]
new byte[1048576]
used: 417
expected usage: 200
import java.io.IOException;
import java.util.ArrayList;
public class Mem {
private static Runtime rt = Runtime.getRuntime();
private static long free() { return rt.maxMemory() - rt.totalMemory() + rt.freeMemory(); }
public static void main(String[] args) throws InterruptedException, IOException {
int blocks = 200;
long initiallyFree = free();
System.out.println("initially free: " + initiallyFree / 1000000);
ArrayList<byte[]> data = new ArrayList<>();
for (int n = 0; n < blocks; n++) { data.add(new byte[1000000]); }
System.gc();
Thread.sleep(2000);
long remainingFree = free();
System.out.println("remaining free: " + remainingFree / 1000000);
System.out.println("used: " + (initiallyFree - remainingFree) / 1000000);
System.out.println("expected usage: " + blocks);
System.in.read();
}
}
使用visualvm更深入地观察,在第一种情况下,我看到一切都符合预期:
在第二种情况下,除了字节数组之外,我看到相同数量的int数组占用与字节数组相同数量的RAM:
顺便说一句,这些int数组没有显示它们被引用,但我无法垃圾回收它们...(字节数组在引用它们的位置显示得很好。
任何想法,这里发生了什么?