Core Java

Compact Object Headers: The Invisible JDK 25 FeatureWith the Biggest Memory Impact

How four saved bytes per object can quietly transform your entire heap — and why you don’t have to change a single line of code.

Every so often, the Java platform ships a change that sits quietly in the release notes — no flashy syntax, no new API, no migration guide — and yet it carries one of the most meaningful real-world payoffs in years. JEP 519, Compact Object Headers, is precisely that kind of feature.

Promoted to a full product feature in JDK 25 (September 2025), this enhancement shrinks the memory overhead that the JVM attaches to every single Java object from 12 bytes down to just 8 bytes. That’s a 33% reduction in header size. And in applications that create millions of objects — which, as it turns out, describes almost every modern Java workload — those four bytes add up surprisingly fast.

In this article, we’ll walk through what object headers actually are, why they matter so much, what changed under the hood, and what the real benchmarks say. By the end, you’ll have everything you need to decide whether to flip the switch in your own services.

1. First Things First: What Is an Object Header?

Before we talk about making object headers smaller, it’s worth understanding what they actually are — because most developers never think about them at all.

In the HotSpot JVM, every Java object stored on the heap carries a small piece of hidden metadata right at the start of its memory layout. This metadata is called the object header, and it consists of two parts:

Header ComponentSize (traditional)Purpose
Mark Word64 bits (8 bytes)Locking state, GC age, identity hash code, biased-lock epoch
Class Pointer32 bits (4 bytes, compressed)Reference to the object’s class metadata in Metaspace
Array Length32 bits (arrays only)Length field appended for array objects

Together, that’s 96 bits (12 bytes) for regular objects on a 64-bit system with compressed class pointers enabled — and 128 bits (16 bytes) without compression. Now here’s the thing that should make you pause: most small Java objects themselves contain only 16–32 bytes of actual data. That means the header alone can account for 20% or more of a typical object’s total memory footprint. In a Spring Boot service with millions of tiny wrapper objects, DTO instances, and collection entries, that tax gets enormous.

Imagine every book in a library came packaged in a rigid plastic case labelled with metadata. Even if the book itself is a short pamphlet, the plastic case never changes size. That’s essentially what a traditional Java object header does — it’s a fixed-cost overhead regardless of how small the object inside is.

2. The Road to JEP 519: A Quick History Lesson

This feature didn’t appear overnight. It’s the result of several years of careful engineering inside the OpenJDK community, most of it driven by Project Lilliput — an initiative specifically focused on shrinking Java object headers. The project was originally kicked off by Roman Kennke at Red Hat, and the journey to production looked like this:

2022- Project Lilliput reaches its first milestone

The team demonstrates a working prototype reducing headers to 64 bits, setting the technical direction for what would follow.

JDK 22 · 2024- Object Monitor Tables infrastructure lands

A necessary stepping stone: locking state is moved out of the header into a side table, making header compression possible without breaking synchronization semantics.

JDK 24 · March 2025- JEP 450 — Compact Object Headers (Experimental)

Available behind -XX:+UnlockExperimentalVMOptions, the feature enters the wild for the first time. Amazon begins testing it in production services.

JDK 25 · September 2025- JEP 519 — Compact Object Headers (Product)

Promoted to a stable product feature. The experimental flag is gone. All it takes is -XX:+UseCompactObjectHeaders.

It’s also worth noting that Amazon and SAP both played key roles in validating this feature. Amazon ran compact headers across hundreds of production services — many using backports to JDK 17 and 21 — before a single production-ready release shipped. SAP went a step further and enabled compact object headers by default in their own JDK 25 fork (SapMachine). That level of real-world confidence is rare, and it tells you a lot about how thoroughly this feature was tested.

3. What Actually Changed Under the Hood

The key insight of Compact Object Headers is elegantly simple: instead of keeping the mark word and the class pointer as two separate fields, they are merged into a single 64-bit word. The class pointer is compressed from 32 bits down to just 22 bits — which still supports approximately 4 million unique classes, far beyond any realistic application requirement. The remaining bits accommodate GC metadata, lock state, hash codes, and four bits reserved for future use by Project Valhalla.

LayoutMark WordClass PointerTotal SizeStatus
Traditional (default)64 bits32 bits96 bits / 12 bytesPre-JDK 25 default
Compact (JEP 519)Merged into single 64-bit word
(22-bit class ptr + GC + lock + hash + 4 reserved bits)
64 bits / 8 bytesJDK 25 opt-in

The change requires Compressed Class Pointers to be enabled (which they are by default on 64-bit systems with heaps under 32 GB). Hash codes and monitor information that used to live directly in the header are now stored in lightweight side tables, indexed by object address — a technique that adds negligible overhead because very few objects actually need those features at any given time.

“Compact object headers eliminate the division between the mark word and the class pointer by subsuming the class pointer in compressed form into the mark word.”— Baeldung, JEP 519 Deep Dive

4. The Numbers: What the Benchmarks Actually Show

Now for the part everyone really wants to know — does this actually make a difference? The benchmarks, sourced directly from the official JEP 519 specification, give a clear and consistent answer: yes, significantly.

SPECjbb2015 Performance Gains with JEP 519

Real benchmark data from the official JEP 519 specification — comparing traditional vs. compact headers across key metrics.

Furthermore, JAVAPRO’s benchmark with 10 million Point objects on JDK 25 found up to 30% less committed memory and 12% less used memory with compact headers enabled. Meanwhile, Spring Boot and microservice workloads typically see 3–5% throughput improvements and 4–6% reductions in P99 latency, according to testing reported by Vinod Jagwani’s analysis.

Estimated Memory Savings by Workload Type

Object-heavy workloads with many small instances benefit the most. Large-object workloads see modest but still measurable gains.

It’s equally important to be honest about where the gains are smaller. If your application primarily deals with large arrays or a handful of long-lived persistent objects, the savings will be less dramatic. The four bytes per object only compound meaningfully when object count is high — and in modern Java, that threshold is crossed more often than not.

5. How to Enable It — and When to Hold Off

Even though JEP 519 is a product feature in JDK 25, it is not enabled by default (though a draft JEP proposing to make it default is already in progress). Enabling it is a single JVM flag

JVM Flag — Enable Compact Object Headers

java -XX:+UseCompactObjectHeaders -jar your-application.jar

If you want to verify the feature is active at startup, you can add the -XX:+PrintFlagsFinal flag and grep for the relevant setting:

Verify the flag is active

java -XX:+UseCompactObjectHeaders -XX:+PrintFlagsFinal -version 2>&1 | grep UseCompactObjectHeaders

You should see output like: bool UseCompactObjectHeaders = true.

Requirements checklist

To use JEP 519, you need:

(1)JDK 25 or later,

(2)a 64-bit system,

(3)Compressed Class Pointers enabled (default on heaps ≤ 32 GB). If your heap exceeds 32 GB, compact headers cannot be used since they depend on compressed class pointer encoding.

That said, there are legitimate reasons to hold off. Highly regulated environments with strict certification requirements, or teams with limited test coverage, may prefer to upgrade the JDK first and enable this feature in a later rollout. The JEP documentation is explicit that this is a conservative, not a correctness, concern — the feature itself is considered fully stable.

Some native code or tooling that relies on assumptions about fixed object layout may need updating to be header-aware. Additionally, ZGC is not currently supported with compact headers — workloads using ZGC will need to switch to G1 or Parallel collectors to take advantage of JEP 519.

6. Why This Matters Most in the Cloud

For on-premises applications running on dedicated hardware, a 22% heap reduction is nice to have. But in cloud and containerised environments, it translates directly into real, measurable cost savings.

Think about it this way: if each container instance needs 22% less heap, you can either run the same number of instances on smaller, cheaper VMs — or pack more instances onto your existing infrastructure. Either way, you’re paying less. As GCEasy’s FinOps analysis notes, this compounds particularly well across microservices architectures, where dozens of services benefit simultaneously.

BenefitMechanismTypical Impact
Heap reduction4 bytes saved per object × millions of objects10–22% less heap used
CPU efficiencyBetter CPU cache utilisation (more objects fit in L1/L2)5–8% less CPU time
GC pressureSmaller heap → fewer and shorter GC cycles15% fewer GC runs
Container densityLower memory per pod → more pods per nodeHigher pod density
Latency (P99)Shorter GC pauses → more consistent response times4–6% P99 improvement

The bottom line: workloads that benefit most from JEP 519 are Spring Boot APIsmicroservices with deep object graphscaching layersORM-heavy applications, and data pipelines where thousands of small DTOs or records are processed in bulk. If your application fits any of those descriptions — and most production Java applications do — this feature is worth enabling and benchmarking.

7. Looking Ahead: What Comes Next for Project Lilliput?

JEP 519 is not the end of the story. The Project Lilliput wiki already outlines work on Lilliput 2, which aims to push object headers down to just 4 bytes. That would be a further 50% reduction on top of what JEP 519 delivers today.

Additionally, the four bits reserved in the current 64-bit header for Project Valhalla hint at deeper integration ahead — particularly around value types, which promise to eliminate object headers entirely for certain kinds of objects by flattening them inline into their containing structure.

Furthermore, a draft JEP is already circulating to make compact object headers the default in a future JDK release. When that happens, every Java application will benefit automatically, without any flag required.

8. What We’ve Learned

In this article, we explored JEP 519 — one of those rare JVM improvements that is completely invisible to your application code yet delivers some of the most tangible performance gains in recent Java history. We started by understanding what object headers are and why their 12-byte size had been a long-standing inefficiency. We then traced the multi-year journey from Project Lilliput through the experimental JEP 450 in JDK 24, all the way to the stable product feature in JDK 25.

We looked at the real benchmark numbers — 22% heap reduction, 15% fewer GC cycles, and 8% less CPU time on SPECjbb2015 — and we learned how a single JVM flag (-XX:+UseCompactObjectHeaders) is all it takes to unlock these gains. Finally, we discussed the cloud cost implications, the workloads that benefit most, and the road ahead with Lilliput 2 and Project Valhalla on the horizon.

Eleftheria Drosopoulou

Eleftheria is an Experienced Business Analyst with a robust background in the computer software industry. Proficient in Computer Software Training, Digital Marketing, HTML Scripting, and Microsoft Office, they bring a wealth of technical skills to the table. Additionally, she has a love for writing articles on various tech subjects, showcasing a talent for translating complex concepts into accessible content.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button