Ответ 1
Это зависит от 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 собрать массив как можно скорее.