javamemory-layoutobjectsize

Why compressed Oops gives 12 bytes for Object Header


This is after Java 6 memory model. In a 32bit JVM, the Shallow size of an object is

8 bytes (object header) + total of all instance variables + padding (optional)

If the first 2 terms don't add upto a multiple of 8 there will be padding.

In a 64 bit JVM, the Shallow size is

16 bytes (object header) + total of all instance variables + padding (optional)

My understanding is that this Object header consists of 2 words (oracle hotspot VM)

on a 32 bit JVM, object header = 2 * 32 bits = 64 bits = 8 bytes
on a 64 bit JVM, object header = 2 * 64 bits = 128 bits = 16 bytes

But using CompressedOops, the 3 lower order bits are truncated so it should be back to 8 bytes on 64 bit JVM for heaps less than 32 gigs

But when i tested the object layout using JOL (Java Object Layout), it shows 12 bytes for Object header.

Test Code

public class App  {
    public static void main( String[] args )
    {
        System.out.println(System.getProperty("java.version"));
        System.out.println(VMSupport.vmDetails());
        System.out.println(ClassLayout.parseClass(A.class).toPrintable());
    } 
}

class A {
   int a; 
}

Output

1.8.0_05
Running 64-bit HotSpot VM.
Using compressed references with 3-bit shift.
Objects are 8 bytes aligned.
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

com.layout.test.jolTesting.A object internals:
 OFFSET  SIZE  TYPE DESCRIPTION                    VALUE
      0    12       (object header)                N/A
     12     4   int A.a                            N/A
Instance size: 16 bytes (estimated, the sample instance is not available)
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

What is it that I'm missing here that adds those additional 4 bytes ?


Solution

  • As far as I know that happens because, contrary to the klass word, the mark word is not encoded by using CompressedOops.

    So 4 bytes (64 bit compressed klass word) + 8 bytes (mark word) = 12 bytes (header)