Fundamentals 10 min read

Why Java 27’s Compact Object Headers Reduce Object Header Size from 12 B to 8 B

Java 27 enables Compact Object Headers, shrinking the default 64‑bit object header from 12 bytes to 8 bytes, which can noticeably lower heap usage for object‑heavy services; the article explains the layout change, demonstrates it with JOL, and offers practical testing guidance for real‑world applications.

LuTiao Programming
LuTiao Programming
LuTiao Programming
Why Java 27’s Compact Object Headers Reduce Object Header Size from 12 B to 8 B

JDK 27 introduces Compact Object Headers, which are enabled by default. The change merges the compressed class pointer into the Mark Word, reducing the object header size on 64‑bit platforms from 12 bytes (96 bits) to 8 bytes (64 bits).

Object header before and after

In the traditional HotSpot layout a typical object consists of:

Mark Word          8 bytes
Class Pointer      4 bytes
... fields ...

Because objects are aligned to 8‑byte boundaries, a simple class with two int fields ( productId and quantity) occupies 24 bytes:

Mark Word          8 bytes
Class Pointer      4 bytes
productId          4 bytes
quantity           4 bytes
padding (alignment)4 bytes
Total             24 bytes

With Compact Object Headers the class pointer is compressed and stored inside the Mark Word, so the header becomes 8 bytes:

Mark Word + Class Pointer   8 bytes
productId                  4 bytes
quantity                   4 bytes
Total                     16 bytes

Thus the same OrderLine instance shrinks from 24 bytes to 16 bytes, a one‑third reduction in the header portion.

Measuring the effect with JOL

The OpenJDK Java Object Layout (JOL) tool can display the actual layout. Example steps:

# Compile the class
public class OrderLine {
    int productId;
    int quantity;
}

# Run JOL with Compact Object Headers disabled (JDK 27)
java -XX:-UseCompactObjectHeaders -cp .:jol-cli.jar org.openjdk.jol.Main internals OrderLine
# Output shows Instance size: 24 bytes

# Run JOL with default settings (Compact Object Headers enabled)
java -cp .:jol-cli.jar org.openjdk.jol.Main internals OrderLine
# Output shows Instance size: 16 bytes

Impact on real services

For applications that allocate large numbers of small objects (DTOs, entities, temporary objects), reducing the header size can noticeably lower overall heap consumption. The benefit is less pronounced when the heap is dominated by large arrays, byte buffers, or big strings, because the header overhead becomes a smaller fraction of total memory.

Testing methodology

To isolate the effect of Compact Object Headers, the article recommends:

Fixing the garbage collector (e.g., -XX:+UseG1GC) to avoid confounding changes such as JDK 27’s default switch to G1.

Running two groups of experiments: one with -XX:-UseCompactObjectHeaders and one with -XX:+UseCompactObjectHeaders, keeping all other JVM flags identical.

Measuring heap usage, GC pause time, allocation rate, old‑gen occupancy, and CPU to assess the real impact.

Enabling or disabling the feature

On JDK 25/26 the flag can be turned on manually:

java -XX:+UseCompactObjectHeaders -Xms2g -Xmx2g -jar app.jar

On JDK 27 it is true by default; you can verify with:

java -XX:+PrintFlagsFinal -version | grep UseCompactObjectHeaders
# Expected output: UseCompactObjectHeaders = true

If compatibility issues arise, the classic layout can be restored with -XX:-UseCompactObjectHeaders.

Broader JVM evolution

The article notes that Compact Object Headers are part of a larger trend where the JVM itself performs more low‑level optimizations (e.g., default G1 GC, virtual threads, improved JFR). These changes often require no code modifications but can affect performance characteristics.

Practical advice

Before upgrading to JDK 27, examine your service’s object allocation patterns to determine whether the header reduction will be beneficial. For workloads with many small objects and high QPS, the memory savings can be significant, especially across many pods in Kubernetes.

Finally, after installing JDK 27, run the flag‑checking command to confirm the feature is active:

java -XX:+PrintFlagsFinal -version | grep UseCompactObjectHeaders
# Should output: true

When the flag is true, you can be confident that the JVM is already applying the compact layout without any code changes.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaJVMMemoryOptimizationCompactObjectHeadersJDK27
LuTiao Programming
Written by

LuTiao Programming

LuTiao Programming is a friendly community offering free programming lessons. We inspire learners to explore new ideas and technologies and quickly acquire job-ready skills.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.