Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)

  • a klass word
  • a mark word

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 ?

like image 824
Arkantos Avatar asked Aug 15 '14 19:08

Arkantos


2 Answers

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)

like image 131
andresp Avatar answered Nov 17 '22 12:11

andresp


HotSpot has 8-byte, 12-byte, and 16-byte object headers. This is because the header contains two parts, markword (metainfo about the object), and classword (the reference to class). In 32/64-bit mode markword takes up either 4 or 8 bytes. Classword is "just" the reference, and hence it can be compressed in 64-bit mode.

see: https://shipilev.net/blog/2014/heapdump-is-a-lie/

like image 2
user3345342 Avatar answered Nov 17 '22 12:11

user3345342