Menjalankan kode di bawah ini pada Windows 10 / OpenJDK 11.0.4_x64 menghasilkan sebagai keluaran used: 197
dan expected usage: 200
. Ini berarti bahwa array 200 byte dari satu juta elemen membutuhkan sekitar. RAM 200MB. Semuanya baik-baik saja.
Ketika saya mengubah alokasi array byte dalam kode dari new byte[1000000]
ke new byte[1048576]
(yaitu, ke 1024 * 1024 elemen), itu menghasilkan output used: 417
dan expected usage: 200
. Apa apaan?
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();
}
}
Terlihat sedikit lebih dalam dengan visualvm, saya melihat dalam kasus pertama semuanya seperti yang diharapkan:
Dalam kasus kedua, selain array byte, saya melihat jumlah array int yang sama dengan jumlah RAM yang sama dengan array byte:
Array int ini, omong-omong, tidak menunjukkan bahwa mereka direferensikan, tapi saya tidak bisa mengumpulkan sampah ... (Array byte menunjukkan dengan baik di mana mereka direferensikan.)
Ada ide apa yang terjadi di sini?
int[]
untuk meniru besar byte[]
untuk lokalitas spasial yang lebih baik?