The most detailed history of java object accounted for a few bytes?

First, download the tool

To analyze the size of an object, a tool to help jol-core, his maven address is:

<dependency>
  <groupId>org.openjdk.jol</groupId>
  <artifactId>jol-core</artifactId>
  <version>0.9</version>
</dependency>

Second, the test

First, a new empty class, which does not contain any field. Then use jol-core print of your object layout.

public class Dog {
}

public class App 
{

    public static void main( String[] args )
    {
        Dog dog =new Dog();
        System.out.println(ClassLayout.parseInstance(dog).toPrintable());
    }
}

He will output the following information, in the end, there is a message for the "Instance size: 16 bytes", saying that the object is 16 bytes.

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           44 c1 00 f8 (01000100 11000001 00000000 11111000) (-134168252)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes

Third, the object memory layout

This is to say where's 16 bytes, must first understand the java object memory layout, that is, as FIG.
Memory layout object into the object header, the actual data objects, filling it.
These three do not discuss with, just know that they accounted for a few bytes on the line, after all, only the object size paper said.
Here Insert Picture Description

3.1 Object head size

The first part is the head of the object, and is divided into Mark Word Class Pointer, different sizes of digits in different JVM.
In the 32-bit system, Mark Word is 4 bytes, Class Pointer is 4 bytes, a total of 8 bytes.
In the 64-bit system, by the influence of the compression pointer, pointer compression is turned on Mark Word is 8 bytes, Class Pointer is 4 bytes, a total of 12 bytes. Close pointer compression Mark Word is 8 bytes, Class Pointer is 8 bytes.

3.2 pointer compression

There in a 64-bit pointer compression concept parameters XX: + UseCompressedOops, is enabled by default, after opening Class Pointer is compressed to 4 bytes, a total of 12 final object header bytes.

Test JVM 64
outputs the compressed pointer opening (default is on), do not control the final size is 16 bytes.

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           44 c1 00 f8 (01000100 11000001 00000000 11111000) (-134168252)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

Then turn off the pointer compression test, click Run configuration in the IDEA, VM options, enter -XX: -UseCompressedOops, on behalf of closed pointer compression.
Here Insert Picture Description
Outputs the result as follows

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           e0 e4 e0 94 (11100000 11100100 11100000 10010100) (-1797200672)
     12     4        (object header)                           07 7f 00 00 (00000111 01111111 00000000 00000000) (32519)
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

You will find the final size is 16 bytes, but there is a line open when compressed (loss due to the next object alignment)size is 4 bytes, this represents the alignment padding, because it requires the size of a multiple of 8, 12 is not a multiple of 8 people originally designed, so but they filled 4. No other significance alignment padding, only for data alignment, is guaranteed to be a multiple of eight.

32-bit JVM test
will need to download a 32 jdk. Then the shortcut keys Ctrl + Alt + Shift + S open configuration item, the selected 32-bit jdk path. Here Insert Picture Description
The result is 8 bytes, the data does not need thereof.

com.hxl.entity.Dog object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           e0 c5 cd a3 (11100000 11000101 11001101 10100011) (-1546795552)
Instance size: 8 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

3.3 actual data

And adding a plastic cha types of fields in the Dog.

public class Dog {
    private int age;
    private char date;
}

64 JVM test
case in the open compression case where the output pointer:

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           44 c1 00 f8 (01000100 11000001 00000000 11111000) (-134168252)
     12     4    int Dog.age                                   0
     16     2   char Dog.date                                   
     18     6        (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 6 bytes external = 6 bytes total

Because int occupies 4 bytes, char 2 bytes, so the size of the original 12 (object header) +4 (int) +2 (char) = 18, but 18 is not a multiple of 8, ah, so data aligned, filled 6, 6 + 18 = 24 bytes.

In the closed compression when the output pointer:

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           10 a5 23 b7 (00010000 10100101 00100011 10110111) (-1222400752)
     12     4        (object header)                           22 7f 00 00 (00100010 01111111 00000000 00000000) (32546)
     16     4    int Dog.age                                   0
     20     2   char Dog.date                                   
     22     2        (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 2 bytes external = 2 bytes total

According to the above mentioned, the size of the original 16 (the object header size) +4 (int) +2 (char ) = 22, two bytes is needed to fill a multiple of 8, so the above output (loss due to the next object alignment)2 bytes.

Test JVM 32
but all in all, in the 32-bit output as the JVM, only 16 bytes.
32 no pointer compression concept, and therefore had a size of 8 (object header) +4 (int) +2 (char ) = 14, but also to fill the second byte is a multiple of eight. So finally 16 bytes.

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           08 c6 cd a3 (00001000 11000110 11001101 10100011) (-1546795512)
      8     4    int Dog.age                                   0
     12     2   char Dog.date                                   
     14     2        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 2 bytes external = 2 bytes total

3.4 reference size

Increase in the name of the dog.

public class Dog {
    private String name;
}

64 test JVM
also in the closed compressed output follows the pointer, 8 bytes found reference type. The final size is 24 bytes.

 OFFSET  SIZE               TYPE DESCRIPTION                               VALUE
      0     4                    (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4                    (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                    (object header)                           f8 34 a0 2f (11111000 00110100 10100000 00101111) (799028472)
     12     4                    (object header)                           3c 7f 00 00 (00111100 01111111 00000000 00000000) (32572)
     16     8   java.lang.String Dog.name                                  null
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

Open pointer compression is different. Reference type occupies 4 bytes. The final size is 16 bytes, which is the reference compressed to 4 bytes of type.

 OFFSET  SIZE               TYPE DESCRIPTION                               VALUE
      0     4                    (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4                    (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                    (object header)                           44 c1 00 f8 (01000100 11000001 00000000 11111000) (-134168252)
     12     4   java.lang.String Dog.name                                  null
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

32JVM Test
32 is the object header of 8 bytes, 4 bytes representing a reference type. A total of 16 bytes plus filling it.

com.hxl.entity.Dog object internals:
 OFFSET  SIZE               TYPE DESCRIPTION                               VALUE
      0     4                    (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4                    (object header)                           f8 c5 dd a3 (11111000 11000101 11011101 10100011) (-1545746952)
      8     4   java.lang.String Dog.name                                  null
     12     4                    (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

3.5 Array types

But if the object is an array, an extra length of the array is shown in the object header. FIG as
Here Insert Picture Description
the following code.

        Dog[] dogs ={new Dog()};
        System.out.println(ClassLayout.parseInstance(dogs).toPrintable());

Red place for the size of the array.
Here Insert Picture Description
Are two arrays, an array of basic data types and the reference data type array, an array of basic data type is calculated as (the number of array x a single element size), such as an array of int, int is 4 bytes each, if there are five elements, They accounted for 20 byte array.

But not the same type of reference, pointer compression open case (array length x4), the 4 bytes of each reference, after closing, each reference 8 bytes, occupies (array length x8) bytes.

Below, the array length is 8, each reference 8 bytes, 64 bytes representing the final (closed pointer compression).

Dog[] dogs ={new Dog(),new Dog(),new Dog(),new Dog(),new Dog(),new Dog(),new Dog(),new Dog()};
System.out.println(ClassLayout.parseInstance(dogs).toPrintable());
[Lcom.hxl.entity.Dog; object internals:
 OFFSET  SIZE                 TYPE DESCRIPTION                               VALUE
      0     4                      (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4                      (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                      (object header)                           20 37 a0 93 (00100000 00110111 10100000 10010011) (-1818216672)
     12     4                      (object header)                           11 7f 00 00 (00010001 01111111 00000000 00000000) (32529)
     16     4                      (object header)                           08 00 00 00 (00001000 00000000 00000000 00000000) (8)
     20     4                      (alignment/padding gap)                  
     24    64   com.hxl.entity.Dog Dog;.<elements>                           N/A
Instance size: 88 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total

On the 32-bit (the number of array x4). The reference element 8 is 32 bytes.

Published 42 original articles · won praise 7 · views 7750

Guess you like

Origin blog.csdn.net/HouXinLin_CSDN/article/details/104222728