L'esecuzione del codice seguente su Windows 10 / OpenJDK 11.0.4_x64 produce come output used: 197e expected usage: 200. Ciò significa che le matrici di 200 byte di un milione di elementi occupano circa. 200 MB di RAM. Tutto bene.
Quando cambio l'allocazione di array di byte nel codice da new byte[1000000]a new byte[1048576](ovvero a 1024 * 1024 elementi), produce come output used: 417e expected usage: 200. Che diamine?
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();
}
}
Guardando un po 'più a fondo con visualvm, vedo nel primo caso tutto come previsto:
Nel secondo caso, oltre agli array di byte, vedo lo stesso numero di array int che occupano la stessa quantità di RAM degli array di byte:
Questi array int, a proposito, non mostrano che sono referenziati, ma non riesco a raccoglierli nell'immondizia ... (Gli array di byte mostrano bene dove sono referenziati.)
Qualche idea su cosa sta succedendo qui?
int[]per emulare una grande byte[]località spaziale migliore?

