Object layout & headers in Java
Object headers, alignment, compact object headers in Java 25.
new Object() has no fields at all, yet it takes 16 bytes of memory. Where do they go?Every object wears a header
Each object starts with a header: a mark word (identity hash code, lock bits, GC age) and a class pointer saying which class it is. Arrays add one more field: their length.
The math of new Object()
On typical 64-bit HotSpot: mark word 8 bytes + compressed class pointer 4 bytes = 12-byte header. Objects are aligned to 8 bytes, so 12 is padded up to 16. Padding fills the gap.
// new Object() on 64-bit HotSpot:
// mark word 8 bytes
// class ptr 4 bytes (compressed)
// padding 4 bytes -> 16 totalSize of a Point
With those defaults, how big is an instance of class Point { int x; int y; }?
16 bytes20 bytes24 bytes
Show the answer
12-byte header + two 4-byte ints = 20, padded up to the next multiple of 8: 24 bytes.
Compact headers in Java 25
JEP 519 made compact object headers a product feature in Java 25: the header shrinks to 8 bytes. It's still opt-in via -XX:+UseCompactObjectHeaders, off by default. With it, that Point fits in 16 bytes.
java -XX:+UseCompactObjectHeaders \
-jar app.jar"Turn off compression to save memory"
-XX:-UseCompressedOops sounds like a tweak, but it does the opposite of saving: references grow from 4 to 8 bytes, so objects get bigger. Compressed references are the default for good reason.
Declaration order?
Does HotSpot lay out an object's fields in memory in the order you declared them?
Think about it, then reveal the answer
Not necessarily. The JVM is free to reorder fields, for example grouping them by size to reduce padding. Tools like JOL (Java Object Layout) show the real layout.
Caches with millions of objects
A cache holding 200 million tiny objects pays a header on every one. On Java 25, -XX:+UseCompactObjectHeaders can cut memory without code changes: each two-int object drops from 24 to 16 bytes. For huge caches, that adds up to gigabytes.
Key takeaways
- Header = mark word + class pointer (+ length for arrays)
- Objects are padded to 8-byte alignment
- Java 25: -XX:+UseCompactObjectHeaders, off by default
- The JVM may reorder fields to reduce padding
HotSpot computes an object's identity hash code lazily: it's generated the first time you call hashCode() (or System.identityHashCode) and then stored in the mark word.
Practice questions
On typical 64-bit HotSpot defaults, how much memory does `new Object()` take?
- 8 bytes
- 12 bytes
- 16 bytes
- 24 bytes
Check your answer
16 bytes. The header is about 12 bytes (8-byte mark word + 4-byte compressed class pointer), and objects are aligned to 8 bytes, so it rounds up to 16.
A cache holds 200 million tiny objects on Java 25. Which option could cut memory use without code changes?
- -Xss512k
- -XX:+UseSerialGC
- -XX:+UseCompactObjectHeaders
- -XX:-UseCompressedOops
Check your answer
-XX:+UseCompactObjectHeaders. Compact headers shrink each header to 8 bytes, which matters most for many small objects. Turning off compressed oops would make references bigger, not smaller.