Skip to content

Object Layout

Java object layout

Provides a good guide to the size of the object header in Java and what it is made up of, for 64bit (compressed oops on and off) and 32 bit JVM.

https://gist.github.com/arturmkrtchyan/43d6135e8a15798cc46c

Excellent guide to memory layout: http://psy-lob-saw.blogspot.com/2013/05/know-thy-java-object-memory-layout.html

Rules

(Taken from psy-lob-saw>)

  • Objects are aligned on 8 byte boundary
  • Fields are also type aligned, long = 8 byte, int = 4 byte, short/char = 2 byte
  • Fields are packed in the order of their size, except for references which are last

The tool jol is a library that can be used to identify the expected size of an object.

Here we see the output for testing with jol on a 64bit compressed oops JVM.

public final class MyClassSingleInt {
    public int value;
}

com.bvb.MyClassSingleInt object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0    12        (object header)                           N/A
     12     4    int MyClassSingleInt.value                    N/A
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

public final class MyClassTwoInts {
    public int int1;
    public int int2;
}

com.bvb.MyClassTwoInts object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0    12        (object header)                           N/A
     12     4    int MyClassTwoInts.int1                       N/A
     16     4    int MyClassTwoInts.int2                       N/A
     20     4        (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

You can see that the second object with two ints, each of size 4 bytes, will lose a total of 4 bytes due to the alignment of the object on 8 byte boundaries.

Object header

See the link above for 32bit, not used that often at this point.

64bit compressed OOP

Mark word is always as wide as the full reference without compressed OOP. But the Klass word can be OOP.

|--------------------------------------------------------------------------------------------------------------|--------------------|
|                                            Object Header (96 bits)                                           |        State       |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                  Mark Word (64 bits)                           |    Klass Word (32 bits)     |                    |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
| unused:25 | identity_hashcode:31 | cms_free:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Normal       |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
| thread:54 |       epoch:2        | cms_free:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Biased       |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                         ptr_to_lock_record                            | lock:2 |    OOP to metadata object   | Lightweight Locked |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                     ptr_to_heavyweight_monitor                        | lock:2 |    OOP to metadata object   | Heavyweight Locked |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                                                       | lock:2 |    OOP to metadata object   |    Marked for GC   |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|

64bit

|------------------------------------------------------------------------------------------------------------|--------------------|
|                                            Object Header (128 bits)                                        |        State       |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                  Mark Word (64 bits)                         |    Klass Word (64 bits)     |                    |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
| unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Normal       |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
| thread:54 |       epoch:2        | unused:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Biased       |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                       ptr_to_lock_record:62                         | lock:2 |    OOP to metadata object   | Lightweight Locked |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                     ptr_to_heavyweight_monitor:62                   | lock:2 |    OOP to metadata object   | Heavyweight Locked |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                                                     | lock:2 |    OOP to metadata object   |    Marked for GC   |
|------------------------------------------------------------------------------|-----------------------------|--------------------|

Klass word


Last update: 2025-09-17