How much space does an object occupy in Java?

How much space does an object occupy in Java? This question depends on the situation. Let's first look at the top-level Object class in Java. It only has methods and no member variables. That is to say, you can know an object by using a new Object object. How much space does a Java object take up at least? We introduce the jol tool to print out the object layout:

First add pom dependencies:

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

Let’s look at Object first:

public class JolMain {
    public static void main(String[] args) {
        Object obj = new Object();
        String layout = ClassLayout.parseInstance(obj).toPrintable();
        System.out.println(layout);
    }
}

The output information is as follows:

java.lang.Object 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)                           e5 01 00 20 (11100101 00000001 00000000 00100000) (536871397)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

It doesn’t matter if you don’t understand it, but we have noticed some key information

12     4        (loss due to the next object alignment)

Instance size: 16 bytes

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

You can see that an Object object occupies 16 bytes, of which 4 bytes are content that does not belong to the object itself and are additionally filled. As for why it is padded, object alignment in Java is to improve the efficiency of memory access. According to the Java Virtual Machine specification, the starting address of an object must be a multiple of a certain size, usually 8 bytes or a power of 2 greater. The purpose of this is to ensure that the fields of the object can be stored in a naturally aligned manner to improve the efficiency of memory access. We add a parameter to the startup parameters: -XX:-UseCompressedOops. The same is the above code. The output results are as follows:

java.lang.Object 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)                           00 1c d3 17 (00000000 00011100 11010011 00010111) (399711232)
     12     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

You can see that there are no additional 4 bytes filled at this time. This UseCompressedOops means whether to turn on the compressed pointer, because there is a type pointer in the Java object header pointing to the type it belongs to. It is turned on by default. This type The pointer occupies 4 bytes, so an Object object actually only occupies 12 bytes by default. For alignment, an additional 4 bytes are filled, and when we do not enable pointer compression, the type pointer stands at 8 Bytes, there is no need for alignment padding at this time.

So how to ensure that filling is not performed by default? Let’s try creating a new User class:

public class User {
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

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

Let’s look at the output: no padding

org.example.jol.User 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)                           54 c3 00 20 (01010100 11000011 00000000 00100000) (536920916)
     12     4    int User.id                                   0
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

We continue to add a long type field (8 bytes) in user:

public class User {
    private int id;
    private long age;

    public long getAge() {
        return age;
    }

    public void setAge(long age) {
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

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

Output: no padding

org.example.jol.User 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)                           54 c3 00 20 (01010100 11000011 00000000 00100000) (536920916)
     12     4    int User.id                                   0
     16     8   long User.age                                  0
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

Continue to add an int type field (4 bytes):

public class User {
    private int id;
    private long age;
    private int uid;

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public long getAge() {
        return age;
    }

    public void setAge(long age) {
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

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

Output: There is padding

org.example.jol.User 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)                           54 c3 00 20 (01010100 11000011 00000000 00100000) (536920916)
     12     4    int User.id                                   0
     16     8   long User.age                                  0
     24     4    int User.uid                                  0
     28     4        (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

It can be seen from this that the space occupied by a Java object is a multiple of 8 bytes. If the actual occupied space does not meet this condition, it will be filled and aligned.

in conclusion:

1. An object in Java occupies at least 16 bytes

2. By default, JVM has pointer compression enabled. The type pointer in the object header occupies 4 bytes. Turning off pointer compression will occupy 8 bytes.

3. The space occupied by Java objects is generally a multiple of 8 bytes. If it is not satisfied, it will be automatically filled to achieve this alignment purpose.

Guess you like

Origin blog.csdn.net/qq_17805707/article/details/132356293