考虑以下类:
public class MemoryTest
{
private long[] longArr; // Eclipse marks this unused
public MemoryTest(int arrSize) {
longArr = new long[arrSize*10];
}
public static void main(String[] args) {
int numObjs = 10000;
MemoryTest[] mts = new MemoryTest[numObjs];
for(int i = 0; i < numObjs; i++) {
// build a large number of objects which hold expensive, unused references
mts[i] = new MemoryTest(i);
//System.gc(); interestingly, uncommenting this line causes OOM earlier
System.out.println("Built "+i+": "+Runtime.getRuntime().freeMemory()/1024+"KB");
}
System.out.println(Arrays.hashCode(mts)); // so elements cannot be GCed earlier
}
}
这失败了:
... truncated output ...
Built 5236: 62070KB
Built 5237: 61661KB
Built 5238: 61252KB
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at MemoryTest.<init>(MemoryTest.java:6)
at MemoryTest.main(MemoryTest.java:15)
显然这是一个人为的例子,但我想知道 GC/JIT 编译器是否可以整理这个longArr
没有在任何地方使用的对象。从 Java 7 开始,现在似乎还没有整理好,但是如果编译器变得更聪明或者我们以某种方式更改示例,这可能会发生,还是 JVM 合同禁止它?