2017-12-11 111 views
5

Khi kích thước bộ nhớ tính toán của một mảng đối tượng, mã sau đây cho "sử dụng 24 byte" như mong đợi, mà, theo như tôi biết, bao gồm:java kích thước mảng đối tượng

4bytes(element pointer)+16bytes(object header)+4bytes(element space) = 24bytes

// with JVM argument -XX:-UseTLAB 
public static void main(String[] args) { 
    long size = memoryUsed(); 
    Object[] o = new Object[]{1}; 
    //Object[] o = new Object[]{1L}; 
    size = memoryUsed() - size; 
    System.out.printf("used %,d bytes%n", size); 
    //Output: used 24 bytes 
} 

public static long memoryUsed() { 
    return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); 
} 

Nhưng khi loại phần tử thay đổi thành Long (1L), kết quả là khó hiểu, phần lớn thời gian là "đã sử dụng 9,264 byte", ai cũng có thể giúp tôi khai sáng? sự khác biệt trong phân bổ bộ nhớ giữa loại phần tử hai này là gì?

// with JVM argument -XX:-UseTLAB 
public static void main(String[] args) { 
    long size = memoryUsed(); 
    //Object[] o = new Object[]{1}; 
    Object[] o = new Object[]{1L}; 
    size = memoryUsed() - size; 
    System.out.printf("used %,d bytes%n", size); 
    //Output: used 9,264 bytes 
} 
+1

Có lẽ để tạo mảng thứ hai, JVM phải nạp các lớp bổ sung (như 'Long' và lớp nội bộ' Long.LongCache') tiêu thụ nhiều bộ nhớ hơn bạn mong đợi. –

+0

Bản sao có thể có của [Trong Java, cách tốt nhất để xác định kích thước của một đối tượng là gì?] (Https://stackoverflow.com/questions/52353/in-java-what-is-the-best-way-to -determine-the-size-of-an-object) –

Trả lời

0

Có một cách tốt hơn để tính toán kích thước đối tượng nói chung, như có một công cụ chuyên dùng cho rằng, gọi là JOL.

Nó không hoàn toàn chính xác như thế nào bạn nghĩ về nó. Tổng kích thước của đối tượng đó sẽ là 40 bytes. Hãy xem nơi không gian này là đến từ:

12 bytes headers (8 bytes + 4 bytes, since there are two headers) 

Bạn nghĩ rằng nó là 16 bytes (8 + 8), nhưng có phải là lựa chọn compressed oops đó là theo mặc định. Bạn có thể tắt nó qua -XX:-UseCompressedOops và thực sự trong trường hợp này kích thước của tiêu đề sẽ là 16 bytes.

4 bytes size of the array (arrays have an int size that is stored in headers) 
4 bytes is the reference size of the Integer (1) 
4 bytes alignment (since objects are 8 bytes aligned - this is the trick behind CompressedOops btw) 

Cho đến nay bạn có 24 bytes cho mảng.

Bây giờ, bạn lưu một Integer bên trong nó, đó là một đối tượng quá, như sau:

12 bytes headers 
4 bytes for the actual int value inside Integer 

Như vậy tổng kích thước là 40 bytes.

+0

Có thể là số nguyên được lưu trữ trong mảng này là kiểu nguyên thủy của nó, do đó, nó tiết kiệm thêm 16byte đối tượng tiêu đề –

+0

@ 鄭 无爲 bạn đã khai báo nó làm một đối tượng ' 'do đó, nó sẽ là' Integer'; nếu bạn muốn lưu không gian đó, bạn cần khai báo nó là 'int []' – Eugene

Các vấn đề liên quan