Compact object headers
A JVM change that shrinks every object on the heap, with no code change at all.
Open this lesson in the learning hubKey points
- Every Java object carries a header: a mark word plus a class pointer, 12 bytes before your fields.
- JEP 519 compresses that to 8 bytes on 64-bit platforms and makes it final in 25.
- For heaps full of small objects the saving is real - often several percent of live heap.
- Smaller objects mean better cache behaviour and less GC pressure, not just a smaller number.
- It is a runtime flag, not a source change: nothing in your code needs to know.
Example
import java.lang.management.ManagementFactory;
public class Main {
record Point(int x, int y) { } // two ints + header
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
System.gc();
long before = rt.totalMemory() - rt.freeMemory();
Point[] points = new Point[500_000];
for (int i = 0; i < points.length; i++) {
points[i] = new Point(i, i * 2);
}
long after = rt.totalMemory() - rt.freeMemory();
long bytesEach = (after - before) / points.length;
System.out.println("objects allocated : " + points.length);
System.out.println("approx bytes each : " + bytesEach + " (header + 2 ints + padding)");
System.out.println("header is 12 bytes on this JVM; Java 25 compacts it to 8");
System.out.println("saving across 500k objects: ~" + (points.length * 4 / 1024) + " KB");
System.out.println("JVM: " + ManagementFactory.getRuntimeMXBean().getVmVersion());
}
}
Compact object headers give a heap saving for free - the win scales with how many small objects you make.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Java 25 Course course, and every lesson in it is listed on the Java 25 Course contents page.