在Windows 10 / OpenJDK 11.0.4_x64上运行以下代码会输出
当我将代码中的字节数组分配从
used: 197
和expected usage: 200
,这意味着200个长度为100万的字节数组大约占用200MB RAM。一切都很好。当我将代码中的字节数组分配从
new byte[1000000]
更改为new byte[1048576]
(即1024 * 1024元素),它会输出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 数组占用与字节数组相同的内存:
这些 int 数组没有显示它们被引用,但我不能对它们进行垃圾回收...(字节数组显示在哪里被引用就行。)
这里发生了什么事情,有什么想法吗?
int[]
来模拟大型byte[]
以获得更好的空间局部性有关吗? - Jacob G.1024*1024 - 2
而不是-16
) - GotoFinal