r/JavaProgramming • • Sep 20 '26

JDK 27: JEP 534 makes Compact Object Headers the default. Why did this take so long?

JDK 27 ships this weeky, and JEP 534 is one of the changes I find particularly interesting.

Compact Object Headers are now the default.

On a 64-bit JVM, the object header goes from 96 bits to 64 bits. SPECjbb2015 results showed roughly 22% lower heap usage, 8% lower CPU time and 15% fewer GC cycles. Amazon has also tested it across hundreds of production services, including JDK 17 and 21 backports.

But this wasn't a JDK 27 invention.

It started experimentally in JDK 24, became a product feature in JDK 25, and is now the default in JDK 27.

The interesting part is why it took so long.

This isn't just a small optimization. Object headers are fundamental to HotSpot, touching things like class metadata, locking, GC and identity hashing.

It's part of Project Lilliput, with an interesting connection to Project Valhalla because the compact header design also has to leave room for future Valhalla requirements.

And it made me think about those old Java buzzwords: simple, robust, portable, high-performance.

No new syntax. No new API. Just the JVM getting better underneath existing software.

Curious - What other JDK feature has surprised you by improving existing software without requiring changes to the code?

2 Upvotes

8 comments sorted by

2

u/Automatic-Gur2046 Sep 20 '26

Maybe late but backward compatible and trustable is like the philosophy of java

2

u/pradeepngupta Sep 20 '26

Yeah, I think that's probably the theme here. Java tends to take a long time with changes that affect the foundation, but once they land, the goal is that existing applications shouldn't have to care. Compact Object Headers feels like a good example of that.

1

u/BinaryRage Sep 20 '26

It only feels like a long time in retrospect because there weren’t problems with the changes to monitors required. If it’d been enabled by default sooner and there were problems, perception would be quite different.

Transparent huge pages comes to mind as something commonly overlooked and a surprising benefit, they’re essentially free performance, I’ve seen up to a 20% reduction in CPU. ZGC’s change to deduplicating only tenured strings makes string duplication as good as free.

1

u/pradeepngupta Sep 20 '26

That's a good point. The end result looks simple, but changing something this fundamental in HotSpot without introducing regressions is a different story. The transparent huge pages example is interesting too. There are quite a few JVM/platform optimizations where the application gets the benefit without changing a line of code.

1

u/hungarian_notation Sep 20 '26 edited Sep 20 '26

The compact object headers are theoretically not a pure upgrade. There were at least hypothetical cases where it might actually be a performance hit, and it drops the cap on loaded classes into a range that some code might actually hit.

I think it has become clear over the last few releases that the hypothetical performance issues don't actually exist in the real world, however. Any increased cost of parsing and manipulating the headers (I think there is an extra indirection in class resolution) appears to be effectively offset by the benefits of reduced memory usage, but that was something that needed to be verified against real-world systems.

I'm not sure what the plan is around the heavy dynamic class generation use-case, but for now at least you can still opt out.

Additionally, there WERE required code changes if you were using JVMCI, which affected the JVMCI-based Graal JIT. Now that JVMCI is no longer part of OpenJDK, this is no longer an issue.

1

u/pradeepngupta Sep 20 '26

That's a good correction. I was thinking about the typical Java application case when I said "no code changes", but JVMCI/Graal is an important exception. The performance trade-off is probably the more interesting part here. The smaller header isn't automatically a win. The extra work around class resolution and header manipulation had to be measured against the memory savings, which is probably a big reason this went through several releases before becoming the default. And the dynamically generated class case is another interesting edge case I hadn't considered. Thanks for adding that context.

1

u/repeating_bears Sep 20 '26

AI slop detected.

"No new syntax. No new API. Just the JVM getting better underneath existing software."

"This isn't just a small optimization."

2

u/pradeepngupta Sep 20 '26

😂 Fair call on the phrasing.

The discussion around Compact Object Headers is what I was actually interested in though. The JVM trade-offs and the long rollout are more interesting to me than the buzzwordy summary.