JEP 450 : Compact Object Headers i
What is JEP 450?
In Java, every object has a header (used for synchronization, identity hashcode, GC, etc.)
Historically, it was 96 bits (12 bytes) on 64-bit platforms
With JEP 450, object headers are now optional and compact — down to 64 bits (8 bytes) when possible
Why does it matter?
More efficient object layout
Better cache locality
Up to 5–10% memory savings in some apps
DEMO
Try to see class layout - attempt 1 - org.openjdk.jol
manual run :
mvn dependency:copy-dependencies
to copy org.openjdk.jol to traget to have it on classpath later
then run :
java \
-XX:+UnlockExperimentalVMOptions \
-XX:+UseCompactObjectHeaders \
-cp "target/classes:target/dependency/*" \
com.wlodar.jeeps.jep450CompactHeaders.CompactHeadersDemo
com.wlodar.jeeps.jep450CompactHeaders.CompactHeadersDemo$SmallObject object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 int SmallObject.x N/A
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
SCRIPT RUN :
This presentation works on openjdk but on azul the same amount of memory is allocated
./scripts/jep450/run-compact.sh compact
./scripts/jep450/run-compact.sh classic
If the same output
JOL cannot tell if the JVM has used compact
headers or not at runtime — it only prints memory layout
assumptions based on class fields, alignment, and architecture.
Try to see class layout - attempt 2 - mass allocation
with method :
private static void allocateMemory(){
WorkshopPrinter.subtitle("Allocating memory");
List<Object> list = new ArrayList<>();
for (int i = 0; i < 10_000_000; i++) {
list.add(new SmallObject());
}
System.gc();
WorkshopPrinter.print("Used memory: " , (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024) + " MB");
}
We have two different results :
./scripts/jep450/run-compact.sh compact
----- Allocating memory
Used memory: : 3 MB
----- Allocating memory
Used memory: : 4 MB
Education :
Last updated