เล่นโค้ดด้านล่างบน Windows 10 / OpenJDK 11.0.4_x64 ผลิตเป็นผลผลิตและused: 197 expected usage: 200ซึ่งหมายความว่าอาร์เรย์ 200 ไบต์ของหนึ่งล้านองค์ประกอบใช้เวลาประมาณ RAM 200MB ทุกอย่างดี
เมื่อฉันเปลี่ยนการจัดสรรอาร์เรย์ไบต์ในรหัสจากnew byte[1000000]ไปnew byte[1048576](นั่นคือ 1024 * 1024 องค์ประกอบ) จะผลิตเป็นผลผลิตและused: 417 expected usage: 200ห่า?
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 ฉันเห็นในกรณีแรกทุกอย่างตามที่คาดไว้:
ในกรณีที่สองนอกเหนือจากอาร์เรย์ไบต์ฉันเห็นจำนวน int อาร์เรย์เดียวกันที่ใช้ RAM ในปริมาณเท่ากันกับอาร์เรย์ไบต์:
โดยวิธีอาร์เรย์เหล่านี้ไม่ได้แสดงว่าพวกเขามีการอ้างอิง แต่ฉันไม่สามารถเก็บรวบรวมขยะพวกเขา ... (อาร์เรย์ไบต์แสดงเพียงแค่ปรับที่พวกเขามีการอ้างอิง)
ความคิดใด ๆ ที่เกิดขึ้นที่นี่
int[]เลียนแบบขนาดใหญ่byte[]สำหรับพื้นที่เชิงพื้นที่ที่ดีกว่าหรือไม่?
                
