这取决于JVM。我尝试过的 Oracle JVM 版本(1.6.0_41 和 1.7.0_09)默认情况下不执行此优化。但是,1.7.0_09 会在开启积极优化时执行它。
这是我进行的测试:
public class Main {
public static int g() {
int n = 100000;
int arr[][] = new int[n][];
for (int i = 0; i < n; ++i) {
try {
arr[i] = new int[100000];
} catch (OutOfMemoryError ex) {
return i;
}
}
return -1;
}
public static void f1() {
int arr[] = new int[1000000];
System.out.println(g());
}
public static void f2() {
int arr[] = new int[1000000];
arr = null;
System.out.println(g());
}
public static void main(String[] argv) {
for (int j = 0; j < 2; ++j) {
for (int i = 0; i < 10; ++i) {
f1();
}
System.out.println("-----");
for (int i = 0; i < 10; ++i) {
f2();
}
System.out.println("-----");
}
}
}
使用具有默认设置的 JVM 1.7,f1()
在 3195 次迭代后始终耗尽内存,而f2()
始终管理 3205 次迭代。
如果代码使用 Java 1.7.0_09 运行,图片会发生变化-XX:+AggressiveOpts -XX:CompileThreshold=1
:两个版本都可以进行 3205 次迭代,表明 HotSpot 在这种情况下确实执行了这种优化。Java 1.6.0_41 似乎没有这样做。
在我的测试中,限制数组的范围与设置引用的效果相同null
,如果您觉得应该帮助 JVM 尽快收集数组,这可能是首选。