Chạy mã dưới đây trên Windows 10 / OpenJDK 11.0.4_x64 tạo ra như đầu ra used: 197
và expected usage: 200
. Điều này có nghĩa là mảng 200 byte của một triệu phần tử chiếm khoảng. RAM 200MB. Mọi thứ đều ổn.
Khi tôi thay đổi phân bổ mảng byte trong mã từ new byte[1000000]
thành new byte[1048576]
(nghĩa là thành 1024 * 1024 phần tử), nó tạo ra như là đầu ra used: 417
và expected usage: 200
. Cái quái gì thế
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();
}
}
Nhìn sâu hơn một chút với visualvm, tôi thấy trong trường hợp đầu tiên mọi thứ như mong đợi:
Trong trường hợp thứ hai, ngoài các mảng byte, tôi thấy cùng một số mảng int chiếm cùng một lượng RAM như các mảng byte:
Nhân tiện, các mảng int này không cho thấy rằng chúng được tham chiếu, nhưng tôi không thể thu thập chúng ... (Các mảng byte chỉ hiển thị tốt ở nơi chúng được tham chiếu.)
Bất kỳ ý tưởng những gì đang xảy ra ở đây?
int[]
mô phỏng lớn byte[]
cho địa phương không gian tốt hơn không?