Aşağıdaki kodu Windows 10 / OpenJDK 11.0.4_x64 üzerinde çalıştırmak çıktı olarak üretir used: 197
ve expected usage: 200
. Bu, bir milyon elementten 200 baytlık dizilerin yaklaşık olarak kapladığı anlamına gelir. 200 MB RAM. Herşey yolunda.
Koddaki bayt dizisi ayırmasını new byte[1000000]
olarak new byte[1048576]
(yani 1024 * 1024 öğelerine) değiştirdiğimde, çıktı used: 417
ve olarak üretilir expected usage: 200
. Ne halt?
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();
}
}
Visualvm ile biraz daha derinlere baktığımda, ilk durumda her şeyi beklendiği gibi görüyorum:
İkinci durumda, bayt dizilerine ek olarak, bayt dizileriyle aynı miktarda RAM alan aynı sayıda int dizisini görüyorum:
Bu int diziler, bu arada, referans alındığını göstermezler, ancak onları çöp toplayamam ...
Burada neler olduğu hakkında bir fikrin var mı?
int[]
büyük bir öykünmek için bir kullanarak JVM ile ilgili bir şey olabilir byte[]
mi?