Tôi đang cố gắng hiểu dấu chân bộ nhớ của một đối tượng trong Java là gì. Tôi đọc this và các tài liệu khác về đối tượng và bộ nhớ trong Java.Dấu chân bộ nhớ đối tượng Java - Visualvm và java.sizeOf đo lường
Tuy nhiên, khi tôi đang sử dụng hình ảnh sizeof Java library hoặc hình ảnh, tôi nhận được hai kết quả khác nhau mà không có kết quả nào chúng tôi mong đợi theo tham chiếu trước đó (http://www.javamex.com).
Để kiểm tra, tôi đang sử dụng Java SE 7 Developer Preview
trên 64-bits Mac
với java.sizeof 0.2.1
và visualvm 1.3.5
.
Tôi có ba lớp, TestObject
, TestObject2
, TestObject3
.
public class TestObject
{
}
public class TestObject2 extends TestObject
{
int a = 3;
}
public class TestObject3 extends TestObject2
{
int b = 4;
int c = 5;
}
lớp học chính của tôi:
public class memoryTester
{
public static void main(String[] args) throws Throwable
{
TestObject object1 = new TestObject();
TestObject2 object2 = new TestObject2();
TestObject3 object3 = new TestObject3();
int sum = object2.a + object3.b + object3.c;
System.out.println(sum);
SizeOf.turnOnDebug();
System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(object1)));
System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(object2)));
System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(object3)));
}
}
Với java.SizeOf() tôi nhận được:
{ test.TestObject
} size = 16.0b
16.0b
{ test.TestObject2
a = 3
} size = 16.0b
16.0b
{ test.TestObject3
b = 4
c = 5
} size = 24.0b
24.0b
Với VisualVM tôi có:
this (Java frame) TestObject #1 16
this (Java frame) TestObject2 #1 20
this (Java frame) TestObject3 #1 28
Theo tài liệu tôi đọc qua Internet, như tôi đang ở 64-bit, tôi nên có tiêu đề đối tượng là 16 byte, ok cho TestObject
.
Sau đó, cho TestObject2
Tôi nên thêm 4 byte cho trường số nguyên cho 20 byte, tôi nên thêm lại 4 byte đệm, cho tổng kích thước 24 byte cho TestObject2
. Liệu tôi có sai?
Tiếp tục theo cách đó cho TestObject3
, tôi phải thêm 8 byte cho hai trường số nguyên phải cung cấp 32 byte.
VisualVm có vẻ bỏ qua phần đệm trong khi java.sizeOf dường như bỏ lỡ 4 byte như thể đã được đưa vào tiêu đề đối tượng. Tôi có thể thay thế một số nguyên bằng 4 boolean nó cho kết quả tương tự.
Câu hỏi:
Tại sao hai công cụ này cho kết quả khác nhau?
Chúng ta có nên có đệm lót không?
Tôi cũng đọc ở đâu đó (tôi đã không tìm thấy liên kết) giữa một lớp và phân lớp của nó có thể có một số phần đệm, đúng không? Trong trường hợp đó, một cây các lớp kế thừa có thể có một số chi phí bộ nhớ?
Cuối cùng, có một số thông số/tài liệu Java nào mô tả chi tiết những gì Java đang làm không?
Cảm ơn sự giúp đỡ của bạn.
Cập nhật:
Để trả lời bình luận của utapyngo, để có được kích thước của các đối tượng trong VisualVM, tôi tạo ra một heapdump, sau đó trong "Lớp học" phần I kiểm tra cột "kích thước" tiếp theo sau khi cột "trường hợp". Số lượng các thể hiện nếu 1 cho mỗi loại đối tượng.
Để trả lời nhận xét của Nathaniel Ford, tôi đã khởi tạo từng fied và sau đó thực hiện một khoản tiền đơn giản với chúng trong phương thức chính để sử dụng chúng. Nó không thay đổi kết quả.
Chúng tôi không có cách nào để biết điều gì là đúng, nếu một trong hai, mà không thấy logic của họ về cách họ đo mức tiêu thụ bộ nhớ. –
Trong trường hợp của tôi jvisualvm 1.7.0 (Build 110325) trên 64-bit Java 1.7.0-b147 cho 16, 16 và 24. Bạn đang sử dụng phương pháp nào để đo bằng visualvm? – utapyngo
Bạn có thể không nhận được kết quả chính xác mà không gán giá trị cho các trường thành viên 'a',' b' và 'c'. Việc triển khai cơ bản của JVM có thể không yêu cầu nó thực sự cấp phát bộ nhớ cho các trường không được sử dụng, chỉ cấp phát bộ nhớ để giữ con trỏ tới các trường đó. –