Mã ở cuối câu hỏi này hơi dài nhưng về cơ bản tạo một vài đối tượng và xác định kích thước của chúng trong bộ nhớ. Tôi thực thi mã với các thông số JVM sau (TLAB để tránh phân bổ bộ nhớ đoạn và được cho là có được số liệu sử dụng bộ nhớ chính xác):Đo chính xác kích thước đối tượng
-server -Xms2000m -Xmx2000m -verbose:gc -XX:-UseTLAB
tôi chạy đoạn code trên 64 bit Hotspot JVM và nhận được kết quả như sau:
Java HotSpot (TM) 64-Bit server VM
Object: 16 byteObject với 1 int: 16 byte
Object với 2 ints: 24 byte
Object với 3 ints: 24 byteObject với 1 dài: 24 byte
Object với 2 chờ đợi: 32 byte
Object với 3 chờ đợi: 40 byteObject với 1 tài liệu tham khảo: 16 byte
đối tượng với sự tham khảo 2: 24 byte
đối tượng với sự tham khảo 3: 24 byte
tôi kết luận rằng:
- đối tượng mất 12 byte, căn chỉnh thành 16 byte.
- một int mất 4 byte (1 đối tượng với một int là 12 + 4 = vẫn 16 byte, với 2 ints: 12 + 8 = 20 liên kết đến 24 byte)
- dài mất 8 byte (1 đối tượng với một dài là 12 + 8 = 20 byte, thẳng đến 24 byte)
Nhưng tôi đấu tranh để hiểu tại sao tài liệu tham khảo không sử dụng không gian nhiều như long
s.
Vì tham chiếu là 8 byte trên JVM 64 bit, kết luận rõ ràng là phương pháp đo lường có lỗi *. Bạn có thể giải thích những gì đang xảy ra và những gì có thể được thực hiện để sửa chữa nó?
* Ghi chú:
- không GC chạy trong khi đo.
- bằng cách sử dụng lược tả Netbeans cho kết quả tương tự.
public class TestMemoryReference {
private static final int SIZE = 100_000;
private static Runnable r;
private static Object o = new Object();
private static Object o1 = new Object();
private static Object o2 = new Object();
private static Object o3 = new Object();
public static class ObjectWith1Int { int i; }
public static class ObjectWith2Ints { int i, j; }
public static class ObjectWith3Ints { int i, j, k; }
public static class ObjectWith1Long { long i; }
public static class ObjectWith2Longs { long i, j; }
public static class ObjectWith3Longs { long i, j, k; }
public static class ObjectWith1Object { Object o = o1; }
public static class ObjectWith2Objects { Object o = o1; Object p = o2; }
public static class ObjectWith3Objects { Object o = o1; Object p = o2; Object q = o3; }
private static void test(Runnable r, String name, int numberOfObjects) {
long mem = Runtime.getRuntime().freeMemory();
r.run();
System.out.println(name + ":" + (mem - Runtime.getRuntime().freeMemory())/numberOfObjects + " bytes ");
}
public static void main(String[] args) throws Exception {
System.out.println(System.getProperty("java.vm.name") + " ");
r = new Runnable() { public void run() { for (int i = 0; i < SIZE; i++) o = new Object(); } };
test(r, "Object", SIZE);
r = new Runnable() { public void run() { for (int i = 0; i < SIZE; i++) o = new ObjectWith1Int(); } };
test(r, "Object with 1 int", SIZE);
r = new Runnable() { public void run() { for (int i = 0; i < SIZE; i++) o = new ObjectWith2Ints(); } };
test(r, "Object with 2 ints", SIZE);
r = new Runnable() { public void run() { for (int i = 0; i < SIZE; i++) o = new ObjectWith3Ints(); } };
test(r, "Object with 3 ints", SIZE);
r = new Runnable() { public void run() { for (int i = 0; i < SIZE; i++) o = new ObjectWith1Long(); } };
test(r, "Object with 1 long", SIZE);
r = new Runnable() { public void run() { for (int i = 0; i < SIZE; i++) o = new ObjectWith2Longs(); } };
test(r, "Object with 2 longs", SIZE);
r = new Runnable() { public void run() { for (int i = 0; i < SIZE; i++) o = new ObjectWith3Longs(); } };
test(r, "Object with 3 longs", SIZE);
r = new Runnable() { public void run() { for (int i = 0; i < SIZE; i++) o = new ObjectWith1Object(); } };
test(r, "Object with 1 reference", SIZE);
r = new Runnable() { public void run() { for (int i = 0; i < SIZE; i++) o = new ObjectWith2Objects(); } };
test(r, "Object with 2 references", SIZE);
r = new Runnable() { public void run() { for (int i = 0; i < SIZE; i++) o = new ObjectWith3Objects(); } };
test(r, "Object with 3 references", SIZE);
}
}
Aargh - Tôi nghĩ rằng 'UseCompressedOops' mặc định là false - nó quay ra nó được kích hoạt theo mặc định. Vâng phát hiện. – assylias
@assylias: Xem bản chỉnh sửa của tôi để biết cách bật/tắt. –