Java Object Size

Do you really know the size of your object?

I was curious to see where I was loosing so much memory in my application when I knew the objects size based on the fields within. This provoked me to write a blog on understanding object structure and calculating its size. All throughout the blog, I have used a class called MSMemory. The fields in the class keep changing to explain size for each.

Configuration:
OS: Windows
RAM: 16GB
JDK: .8.0_171 64 bit

I use jmap to get the heap dump. The command is below (Use jps to get the java process id):

jmap -dump:format=b,file=heap.bin <java_process_id>

Then i use jhat to analyse the heap dump. The command is below:

jhat heap.bin

Jhat starts a HTTP server on port 7000 by default. Port number is configurable.


1. Class MSMemory has no fields. Size is for one instance of MSMemory.

public class MSMemory {}

/*Main class*/
public class MemoryAnalyser {
public static void main(String[] args) {
MSMemory memory = new MSMemory();
}
}

Heap Histogram: Shows one instance with size 0. Clicking on the class takes you to the size of each object.






On Click of MSMemory class, it takes to the below screen where the holding object size is shown.

Size:16 bytes. Why is empty object occupying so much memory? That is Object Header. All objects will have the overhead of 16 bytes (in 64 bit JVM). You'll understand it better with more examples below.


2. Class MSMemory has one primitive int. I create one instance of MSMemory
It has just primitive variable int i

public class MSMemory {
int i;
}

Histogram Memory:






























Conclusion: Object Header 16 bytes + Primitive int 4 bytes.

3. Class MSMemory has one Integer integer which is null. I create one instance of MSMemory.

public class MSMemory {
Integer integer;
}





















Conclusion: Object Header 16 bytes + Integer 8 bytes


4. Class MSMemory has one Integer integer which is null and one int . I create one instance of MSMemory.

public class MSMemory {
int i;
Integer integer;

public static void main(String[] args) {
MSMemory memory = new MSMemory();
       }
}

Histogram Memory:
































Conclusion: Object Header 16 bytes + Null Integer reference 8 bytes + Primitive int 4 bytes

5. Class MSMemory has one Integer integer which assigned a value. Size is for one instance of MSMemory.


public class MSMemory {
Integer interger = 8;
}

Heap Histogram:








References:













Click on it, you'll see that the integer is holding reference to another object of size 20 bytes














The Integer object is 20 bytes which is 16 bytes of object header + 4 bytes primitive int which it holds internally!





















Conclusion: Object Header of MSMemory 16 bytes + 8 bytes Integer reference + Object Header for Integer object 16 bytes + Primitive int 4 bytes = 44 bytes

To be continued...
Size for String, Double, Long, Collections, etc

Coming up next will be an API to calculate the size of any object.


PS: This is my first blog. There is a lot of scope for improvement in the presentation. I will try to catch up in the future blogs. I will promise to keep the topics interesting!



Comments

Popular posts from this blog

Analyzing Thread Dump Made Easy

Does wait() method have to be called from synchronized method or block?