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 ?