[Java Basics] Java Object Memory Structure

Source: Internet
Author: User

Reprint Address: http://www.importnew.com/1305.html

Published on November 13, 2008, December 18, 2008 Update: There is also an article about the Java sizeof Operator's utility library.

I am a little confused about Java, which is the lack of a mechanism for calculating the size of objects that occupy memory. In C + +, you can use the sizeof operator to get the base type and the size of the class instance. This operator in C and C + + is useful for pointer arithmetic, memory copy, and IO operations.

There is not a similar operator in Java. In fact, Java does not need this operator either. The size of the base type in Java is already defined in the language specification, whereas the base type size in C + + is related to the platform. Java has its own IO framework built by serialization. Furthermore, because there are no pointers in Java, operations such as pointer arithmetic and memory block copying do not exist.

However, Java programmers sometimes want to know exactly how much memory a Java object is using. But the answer to this question is not simple.

The first thing to distinguish clearly is the shallow size and the deep size. Shallow size refers to the amount of memory occupied by the object itself, and the size of the reference object is not counted. The deep size is the sum of the memory size of the memory that it occupies and all the objects it recursively references. In most cases, you will want to get the deep size of an object, but in order to know this value, first you need to know how to calculate shallow size, let me introduce you.

There are complaints that there is no description of the memory structure of the runtime Java objects in the JVM specification, which means that the JVM vendor can do this as needed. As a consequence, the size of memory used by instance objects running on different JVMs by the same class can vary. Fortunately, most people in the world, including me, use the Sun hotspot virtual machine, which greatly simplifies this problem. Our next discussion will also be based on the 32-bit Sun Company's JVM. Here are some rules to help explain how the JVM organizes objects in-memory layouts.

Memory layout for classes with no instance properties

In the Sun JVM, objects (except for arrays) have two machine word (words) heads. The first word contains the hash code of the object and some other similar lock status and other identifying information, and the second word contains a reference to the object's class. In addition, any object is 8 bytes aligned to a granularity. This is the first rule for object memory layout:

Rule 1: Any object is 8 bytes Grain size Alignment the.

For example, if you call new Object (), because there is no other member of the object class that can be stored, only 8 bytes in the heap are used to hold the two-word header.

Memory layout of the class that inherits the object

In addition to the 8-byte header mentioned above, the class attribute is immediately followed. Properties are usually arranged according to their size. For example, integers (int) are aligned in 4-byte units, and long integers are aligned in 8-byte units. This is designed for performance reasons: Typically, if the data is aligned in 4-byte units, then reading 4 bytes of data from memory and writing to the processor's 4-byte register is more cost-effective.

To conserve memory, Sun VMS do not have a memory layout in the order in which they are declared. In fact, the properties are organized in memory in the following order:

1. Double type (doubles) and long Integer (longs)

2. Integral type (ints) and float type (floats)

3. Short integer type (shorts) and character type (chars)

4. Boolean type (booleans) and byte type (bytes)

5. Reference type (References)

Memory utilization is optimized through this mechanism. For example, declare a class as follows:

class MyClass {        byte  A;         int C;         Boolean D;         Long e;        Object f;          }

If the JVM does not disrupt the declaration order of attributes, its object memory layout will look like this:

[HEADER:  8 bytes]  8[A:       byte ]  93 bytes][C:       4 bytes] 16 [D:       byte ]7 bytes]       [e:8 bytes][f:       4 Bytes]4 bytes] 40

At this point, the 14 bytes used for the placeholder are wasted, and the object uses a total of 40 bytes of memory space. However, if these objects are reordered with the rules above, their memory results will look like this:

[HEADER:  8 bytes]  8[e:       8 bytes][C:       4 bytes][A:       byte ] [       D:byte ] 2 bytes][f:       4 bytes]4 bytes] 32

This time, only 6 bytes are used for the placeholder, and this object uses 32 bytes of memory space.

Therefore, the second rule for object memory layout is:

Rule 2: Class attributes are arranged according to the following precedence: long and double types, integer and float, character and short, byte type and Boolean type, and finally reference type. These properties are aligned according to their respective units.

Now we know how to calculate the memory size of an instance of a class that inherits object. The following example is used to do the following exercise: Java.lang.Boolean. This is its memory layout:

[HEADER:  8 bytes]  8[value:   byte ]  97 bytes] 16

Instances of the Boolean class consume 16 bytes of memory! Surprised, huh? (Don't forget the last 7 bytes used to occupy the bit).

Inheriting memory layouts for subclasses of other classes

The following 3 rules are used by the JVM to organize members of classes that have a parent class. Rule 3 for Object memory layout is as follows:

Rule 3: Members in a non-homogeneous inheritance relationship cannot be mixed. The members of the parent class are processed first by rule 2, followed by the members of the subclass.

Examples are as follows:

class a {   long  A;    int b;    int  classextends  A {   long  D;}

The instance of Class B is stored in memory as follows:

[HEADER:  8 bytes]  8[A:       8 bytes][B:       4 bytes][C:       4 Bytes][d:       8 bytes] 32

If the size of a member in the parent class does not satisfy the basic unit of 4 bytes, then the next rule will work:

Rule 4: When the last member of the parent class and the first member of the subclass have not enough 4 bytes, they must be expanded to a base unit of 4 bytes.

Examples are as follows:

class A {   byteclass  b {   byte  b;} [HEADER:   8 bytes]  8[A:       byte ]  93 bytes][       B:byte ]3 bytes] 16

Note that member A is expanded by 3 bytes to ensure that the interval between and member B is 4 bytes. This space cannot be used by Class B and is therefore wasted.

The last rule saves some space under the following conditions: If the subclass member is a long integer or double type, and the parent class does not run out of 8 bytes.

Rule 5: If the first member of a subclass is a double or long integer, and the parent class does not run out of 8 bytes, the JVM breaks Rule 2, filling in the unfilled space in the Order of shaping (int), short integer (shorter), byte type (byte), reference type (reference).

Examples are as follows:

class A {  byteclass  b {  long  b;    Short C;    byte D;}

Its memory layout is as follows:

[HEADER:  8 bytes]  8[A:       byte ]  93 bytes][C:       2 bytes] 14 [D:       byte ] []       [b:8 bytes] 24

At the 12th byte, where Class A "ends", the JVM does not obey Rule 2, but inserts a short integer and a byte member before the long integer, which avoids wasting 3 bytes.

Memory layout of an array

The array has an additional head member that is used to hold the "Length" variable. Array elements and the array itself, as well as other regular objects, are subject to the 8-byte boundary rule.

The following is a memory layout for a byte array with 3 elements:

[HEADER:  bytes] [[0]:      byte ] [[1]:      byte ][[2]:      byte ]  [padding:byte ] 16

The following is a memory layout of a long integer number with 3 elements:

[HEADER:  bytes] [padding:  4 bytes] [[0]:      8 bytes][[1]:      8 bytes][[2]:      8 bytes] 40

Memory layout for internal classes

A non-static inner class (Non-static inner classes) has an additional "hidden" member, which is a reference variable that points to an external class. This member is a normal reference and therefore adheres to the rules that reference the memory layout. The inner class therefore has a 4-byte extra overhead.

The last bit of thought

We have learned how to calculate the shallow size of a Java object in a 32-bit sun JVM. Knowing how memory is organized helps to understand how much memory the class instance occupies.

In the next article, there will be some sample code that organizes the relevant content together and uses reflection (reflection) to calculate the deep size of an object. If you are interested, please subscribe to this feed or wait for this blog update!

English Original: Code instructions, translation: Importnew-Zhengwen

Link: http://www.importnew.com/1305.html

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.