JEP 534: Compact Object Headers by Default
Introduction
Some performance optimizations live so deep in the language that you do not even know they exist. The object header is one such place, silently occupying a few bytes at the very front of every Java object. You never declared it, yet you pay for it every time you create an object. JEP 534 cuts this invisible overhead by a third to a half, and you do not have to change a single line of code.
What is an object header?
Every object on the Java heap, before the fields you defined by hand, hides a block of metadata called the object header.
- Every Java object carries a hidden header before its fields. Write
new Point(x, y)and what actually sits in memory is not justxandy, there is an invisible header in front. - Its mark word holds runtime information such as the object's hash code, GC age, and locking state.
- It also holds a class pointer identifying the object's type, so the JVM knows "what kind of object this is."
- On 64-bit HotSpot, this has traditionally cost 96 bits, that is, 12 bytes.
Why the header size matters
You might think 12 bytes is nothing. But here is the key: typical Java heaps are dominated by small objects.
- An object with just two or three fields can have a header as large as, or larger than, its own fields. A 12- or 16-byte header on an object that itself holds only a dozen bytes of useful data easily means the overhead is more than half.
- The smaller the object, the more the header dominates. And that directly erodes cache utilization: CPU cache lines move data in fixed-size chunks (usually 64 bytes), and if a cache line fills up with header metadata, there is less room for useful data. Every memory access pays for a pile of header information you do not care about.
- More heap traffic means more GC work and more memory bandwidth. Every byte the header occupies has to be allocated, copied, collected, and scanned. Multiply that fixed overhead across a vast number of small objects and it adds up to a meaningful performance loss.
What JEP 534 changes
JEP 534 makes Project Lilliput's compact object headers the default.
- Compact object headers become the default behavior.
- On 64-bit architectures, the header shrinks from 96 bits to 64 bits, that is, from 12 bytes to 8 bytes.
- The key trick that makes this possible: merging the mark word and the compressed class pointer into a single 64-bit word. Two pieces of information that each used to occupy their own space are cleverly packed into one word.
- On the evolution path, this feature shipped experimental in JDK 24, became a product option in JDK 25, and in JDK 27 finally becomes the default as a natural next step.
Impact: measured effects and compatibility notes
Measured effects:
- The JEP reports a 15% reduction in GC count in one SPECjbb2015 experiment and a 10% reduction in time for a highly parallel JSON parser benchmark.
- Better cache locality and fewer GC cycles. The same cache line holds more useful objects, and the heap traffic GC has to process drops accordingly.
- Throughput gains from reduced allocation pressure. Smaller objects mean faster allocation and cheaper collection, improving overall throughput.
Compatibility notes:
- If you hit problems, you can temporarily opt out with
-XX:-UseCompactObjectHeadersand fall back to the old header layout. - Agents or tools that assume the header layout may need updates. A small number of low-level tools that directly depend on the header memory layout (certain profilers, serialization frameworks, or JVMTI agents) need to adapt to the new layout.
- Class-pointer space is bounded, so with a very large number of classes, this is a limit to watch.
For the vast majority of applications, though, none of this is an issue, you benefit without changing a line of code.
Conclusion
Without touching any code, just upgrade to JDK 27 and your objects automatically "slim down," with performance gains following. This is a pure JVM-level optimization, completely transparent to the application layer. That is exactly its beauty: you do nothing, yet the payoff shows up in real workloads. It is object slimming for free.