Dipende dalla JVM. Le versioni di Oracle JVM che ho provato (1.6.0_41 e 1.7.0_09) non eseguono questa ottimizzazione di default. Tuttavia, 1.7.0_09 lo esegue quando si attivano le ottimizzazioni aggressive.
Ecco è il test che ho condotto:
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("-----");
}
}
}
Utilizzando JVM 1.7 con le impostazioni predefinite, f1()
corre costantemente la memoria dopo 3195 iterazioni, mentre f2()
gestisce costantemente 3205 iterazioni.
L'immagine cambia se il codice viene eseguito utilizzando Java 1.7.0_09 con -XX:+AggressiveOpts -XX:CompileThreshold=1
: entrambe le versioni possono eseguire iterazioni 3205, a indicare che in questo caso HotSpot esegue l'ottimizzazione. Java 1.6.0_41 non sembra farlo.
Nel mio test, restringere l'ambito dell'array ha lo stesso effetto dell'impostazione del riferimento null
e probabilmente dovrebbe essere la scelta preferita se si ritiene che si dovrebbe aiutare la JVM a raccogliere l'array al più presto.
forse, probabilmente. – Cubic
Si potrebbe semplicemente circondare il codice con parentesi. – MikeTheLiar
'data = null' lo rende idoneo alla raccolta differenziata. –