Java Objects Memory Structure (RPM)

Source: Internet
Author: User

Original Address http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html

Update (December 18th): I ' ve posted here a experimental library that implements Sizeof for Java.


One thing about Java-have always bothered me, given my C + + roots, is the lack of a-a-to-figure out how much memory is used by an object. C + + features the sizeof operator, that lets you query the size of primitive types and also the size of objects of a given Class. This operator in C and C + + are useful for pointer arithmetic, copying memory around, and IO, for example.

Java doesn ' t has a corresponding operator. In reality, Java doesn ' t need one. Size of primitive types in Java was defined in the language specification, whereas in C and C + + it depends on the platform. Java have its own IO infrastructure built around serialization. And both pointer arithmetic and bulk memory copy don ' t apply because Java doesn ' t has pointers.

But every Java developer at some point wondered how much memory are used by a Java object. The answer, it turns out, are not so simple.

The first distinction to being made is between Shallow Sizeand Deep size. The shallow size of an object was the space occupied by the object alone, not taking to account size of other objects tha T it references. The deep size, in the other hand, takes to account the shallow size of the object, plus the deep size of each object ref Erenced by this object, recursively. Most of the times you'll be interested on knowing the deep size of a object, but, with order to know that, you need to kn ow how to calculate the shallow size first, which are what I'm going to talk on here.

One complication is this runtime in memory structure of Java objects are not enforced by the virtual machine specification, Which means that virtual machine providers can implement them as they. The consequence is so you can write a class, and instances of this class in one VM can occupy a different amount of memo RY than instances of this same class when the run in another VM. Most of the world, including myself, uses the Sun HotSpot virtual machine though, which simplifies things a lot. The remainder of the discussion would focus on the ' the ' Sun JVM. I'll lay down a few ' rules that would help explain how the JVM organizes the objects ' layout in memory.

Memory layout of classes that has no instance attributes

In the Sun JVM, every object (except arrays) has a 2 words header. The first word contains the object ' s identity hash code plus some flags like lock state and age, and the second word conta Ins a reference to the object ' s class. Also, any object was aligned to an 8 bytes granularity. This is the first rule or objects memory layout:

Rule 1:every object is aligned to an 8 bytes granularity.
Now we know the if we call new Object(), we'll be a using 8 bytes of the heap for the both header words and nothing else, since the ObjectClass doesn ' t has any fields.

Memory layout of classes that extend Object

After the 8 bytes of the header, the class attributes follow. Attributes is always aligned in memory to their size. For instance, INTs is aligned to a 4 byte granularity, and longs is aligned to an 8 byte granularity. There is a performance reason to does it this way:usually the cost to read a 4 bytes word from memory into a 4 bytes regist Er of the processor is much cheaper if the word was aligned to a 4 bytes granularity.

In order to save some memory, the Sun VM doesn ' t lay out object's attributes in the same order they is declared. Instead, the attributes is organized in memory in the following order:
    1. Doubles and longs
    2. INTs and floats
    3. Shorts and chars
    4. Booleans and bytes
    5. References

This scheme allows for a good optimization of memory usage. For example, imagine you declared the following class:
class MyClass {    byte A;    int C;    Boolean D;    Long e;    Object F;        }

If the JVM didn ' t reorder the attributes, the object memory layout would is like this:
[HEADER:  8 bytes]  8[a:       1 byte]  9[padding:3 bytes] 12[c:       4 bytes] 16[d:       1 byte] 17[padding : 7 bytes] 24[e:       8 bytes] 32[f:       4 bytes] 36[padding:4 bytes] 40

Notice that bytes would has been wasted with padding and the object would use bytes of memory. By reordering the objects using the rules above, the in memory structure of the object becomes:
[HEADER:  8 bytes]  8[e:       8 bytes] 16[c:       4 bytes] 20[a:       1 byte] 21[d:       1 byte] 22[padding:2 bytes] 24[f:       4 bytes] 28[padding:4 bytes] 32

This time, only 6 bytes is used for padding and the object uses only bytes of memory.

So this is rule 2 of object memory layout:

Rule 2:class attributes is ordered like This:first longs and doubles; then ints and floats; then chars and shorts; Then bytes and Booleans, and the references. The attributes is aligned to their own granularity.
Now we know how to calculate the memory used by any instance of a class that extends Object directly. One practical example is the Java.lang.Boolean class. Here's its memory layout:
[HEADER:  8 bytes]  8 [Value:   1 byte]  9[padding:7 bytes] 16

An instance of the Boolean class takes bytes of memory! Surprised? (Notice the padding at the end to align, the object size to an 8 bytes granularity.)

Memory layout of subclasses of other classes

The next three rules is followed by the JVM to organize, the the fields of classes, which have superclasses. Rule 3 of Object memory layout is the following:

Rule 3:fields, belong to different classes of the hierarchy is never mixed up together. Fields of the superclass come first, obeying Rule 2, followed by the fields of the subclass.
Here are an example:
class A {   long A;   int b;   int C;} class extends A {   long D;}

An instance of B looks like this in memory:
[HEADER:  8 bytes]  8[a:       8 bytes] 16[b:       4 bytes] 20[c:       4 bytes] 24[d:       8 bytes] 32

The next rule is used when the fields of the superclass don ' t fit in a 4 bytes granularity. Here's what it says:

Rule 4:between The last field of the superclass and the first field of the subclass there must being padding to align to a 4 Bytes boundary.
Here are an example:
class A {   byte A;} class b {   byte B;}
[HEADER:  8 bytes]  8[a:       1 byte]  9[padding:3 bytes] 12[b:       1 byte] 13[padding:3 bytes] 16

Notice the 3 bytes padding after field aTo align bTo a 4 bytes granularity. That space is lost and cannot are used by fields of class B.

The final rule is applied-save some space when the first field of the subclass is a long or double and the parent class Doesn ' t end in an 8 bytes boundary.

Rule 5:when The first field of a subclass is a double or long and the superclass doesn ' t align to an 8 bytes boundary, JV M would break rule 2 and try to put a int, then shorts, then bytes, and then references at the beginning of the space Rese RVed to the subclass until it fills the gap.
Here are an example:
class A {  byte A;} class b {  long B;  Short C;    byte D;}

Here is the memory layout:
[HEADER:  8 bytes]  8[a:       1 byte]  9[padding:3 bytes] 12[c:       2 bytes] 14[d:       1 byte] 15[padding: 1 byte] 16[b:       8 bytes] 24

At byte (which is where class A ' ends '), the JVM broke rule 2 and stuck a short and a byte before a long, to save 3 out of 4 bytes that would otherwise has been wasted.

Memory layout of arrays

Arrays has a extra header field that contain the value of the ' length ' variable. The array elements follow, and the arrays, as any regular objects, is also aligned to an 8 bytes boundary.

Here are the layout of a byte array with 3 elements:
[HEADER:  bytes] 12[[0]:      1 byte [13[[1]:      1 byte] 14[[2]:      1 byte] 15[padding:  1 byte] 16

And here are the layout of a long array with 3 elements:
[HEADER:  bytes] 12[padding:  4 bytes] 16[[0]:      8 bytes] 24[[1]:      8 bytes] 32[[2]:      8 bytes] 40

Memory layout of inner classes

Non-static inner classes has an extra ' hidden ' field which holds a reference to the outer class. This field was a regular reference and it follows the rule of the in memory layout of references. Inner classes, for this reason, has an extra 4 bytes cost.

Final Thoughts

We have learned-calculate the shallow size of any Java object in the "Sun JVM". Knowing how memory are structured can help you understand how much memory is used by instances of your classes.

In the next post I'll show code that puts it all together and uses reflection to calculate the deep size of an obje Ct. Subscribe to my feeds or keep watching this blog for updates!

Java Objects Memory Structure (RPM)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.