This article is participating in the “Java Theme Month – Java Brush questions card”, activity link

The title

Memory structure analysis of Java objects

knowledge

The memory structure of Java objects in the JVM is divided into three blocks: Object Header, Instance Data, and Padding. Object header: flag field, type pointer, array length (limited to array objects).

The size of the data associated with the main part of the object header:

  • Object Header

    • Mark Word: The Mark Word part of the object is 4 bytes and contains a series of tag bits, such as the lightweight tag bit (00), biased lock tag bit (01), and so on.

    • Class object pointer: The Class object pointer is also 4 bytes in size and points to the memory address of the corresponding Class object (its corresponding metadata object).

  • Object actual data: this contains all member variables of the object. The size is determined by the size of each member variable. For example: Byte and Boolean are 1 byte, short and char are 2 bytes, int and float are 4 bytes, long and double are 8 bytes, and refrence is 4 bytes.

  • Alignment fill: The last part is the alignment of the filled bytes, in 8 bytes

Points to note:

Object Header

Mark Word (Mark field)

Used to store the runtime data of the object itself, such as HashCode, GC generation age, lock status flags, thread held locks, biased thread ids, and so on. Mark Word is designed as a flexible data structure to store as much information as possible in a very small space. It reuses its storage space according to its state.

Klass Pointer

Object is a pointer to its class data, which the virtual machine uses to determine which class instance the object is.

Length = Length

If the object is a Java array, there must also be a block of data in the object header that records the length of the array.

Because a virtual machine can determine the size of a Java object from the metadata information of a normal Java object, it cannot determine the size of an array from the metadata of an array.

In a 32-bit JVM, the size of the Class pointer is 4 bytes, the size of the Mark Word is 4 bytes, so the header is 8 bytes, and if it is an array, 4 bytes are added to indicate the length of the array, as shown in the following table:

In a 64-bit JVM, when pointer compression is turned on, the size of the Class pointer in the header is still 4 bytes, and the Mark Word area is enlarged to 8 bytes, which means the header is at least 12 bytes, as shown in the figure below:

Instance Data

  • The instance data holds the field information of the object. Whether inherited from a parent class or defined in a subclass is stored in the instance data. In order that the fields defined by the parent class appear before the variables defined by the child class.

Note: The order in which this data is stored is affected by the order in which the vm allocation parameters (FieldAllocationStyle) and fields are defined in the Java source code.

The default HotSpot VM allocation policy is as follows:

Longs/Doubles, INTS, shorts/chars, Bytes/Booleans, OOP (Ordinary Object Pointers)Copy the code
  • As you can see from the allocation strategy, fields of the same width are always assigned together

  • If this premise is met, variables defined in the parent class appear before subclasses

CompactFields = true;

If the CompactFields parameter is true (the default is true), narrower variables in the subclass may also be inserted into the gap between the parent class variables.

  • Aligned padding: Aligned padding is not necessarily there and has no particular meaning. It serves only as a placeholder. Since HotSpot VM’s automatic memory management system requires that the object’s starting address be an integer multiple of 8 bytes, that is, the object’s size must be an integer multiple of 8 bytes. The object header part is a multiple of 8 bytes, so when the object instance data part is not aligned, it needs to be completed by alignment padding

extends

Practical case analysis

Note: The markdown in the picture is wrong, it should be markword, please forgive me! .

In HotspotJVM, how many times the size of an Integer object is int on a 32-bit machine?

We all know that in the Java language specification the size of an int is 4 bytes, so what is the size of an Integer object? To know the size of an object, you need to know how it is structured in the virtual machine. Let’s look at the structure of Hotsopt objects in memory:

As can be seen from the above figure, the object’s structure in memory mainly consists of the following parts:

Based on the above figure, we can derive the structure of an Integer object as follows:

Integer has only one value of type int, so the size of the actual data portion of the object is 4 bytes, followed by another 4 bytes to achieve an 8-byte alignment, so the size of the Integer object is 16 bytes.

Thus, we can conclude that an Integer object is four times the size of a native int.

Regarding the memory structure of objects, it is important to note that the memory structure of arrays is slightly different from that of ordinary objects, because the data has a length length field. The object header is followed by a length field of type int (4 bytes), followed by the data in the array. The diagram below: