Java’s Identity Crisis Ends: Project Valhalla Lands in JDK 28
Value classes finally arrive as a preview in JDK 28, bringing bare-metal performance to Java's object-oriented abstractions.
For over a decade, a running joke has quietly circulated among Java developers: we would sooner find ourselves in the Norse afterlife of Valhalla than see the namesake OpenJDK project actually ship. That joke has officially been retired.
Oracle software engineer Lois Foltan recently confirmed that JEP 401 (Value Classes and Objects) has been integrated into the mainline OpenJDK repository, targeting JDK 28 for March 2027. The sheer scale of this integration is staggering. The pull request alone introduces more than 197,000 lines of code across 1,816 files—a change so massive that other committers were asked to pause large commits to ensure a smooth landing.
Sponsored by the HotSpot Group, Project Valhalla represents the most fundamental rewrite of the Java object model since the introduction of generics in Java 5. By stripping identity from objects, Valhalla aims to fulfill a long-held promise: "codes like a class, works like an int." For developers, this is not just an incremental performance boost; it is a profound shift in how we design, allocate, and reason about data in the JVM.
The "Fluffy" Heap: Why Java Needed a Rewrite
To appreciate why Valhalla took a decade of design work, we have to look back to Java’s 1995 foundation. Java divides the world into two categories: eight primitive types (int, double, boolean, etc.) and reference types.
When you instantiate a reference type—say, Point p = new Point(1, 2)—the variable p does not hold the point itself. It holds a pointer, essentially a "coat-check number" pointing to a location on the heap where the object resides. Every time your code reads a field, the JVM must perform pointer indirection, hopping to that heap address.
At scale, this layout becomes what Java Language Architect Brian Goetz calls "fluffy." Every object on the heap requires its own header—a dozen or so bytes of metadata used for locking, synchronization, and garbage collection. If you allocate an array of one million Point objects, you do not get a dense block of memory. Instead, you get an array of one million pointers pointing to one million scattered memory boxes.
This layout made sense in 1995 when memory access speeds were roughly on par with CPU operations. Today, however, CPUs are orders of magnitude faster than main memory. Modern processors rely heavily on cache lines (typically 64 bytes) to load contiguous chunks of data into L1/L2 cache. When data is scattered across the heap, pointer-chasing causes frequent cache misses, slowing execution down significantly.
While the JVM's escape analysis can sometimes optimize these allocations away by spreading object fields into local variables or registers, this optimization is notoriously fragile. If an object is stored in an array, passed into a complex method, or assigned to a field of another class, escape analysis fails. Developers are left with a choice: accept the performance penalty, or write unreadable "brute-force" code—such as flattening a Color class into raw, primitive byte arrays—to force memory density.
JEP 401 and the Death of Object Identity
JEP 401 solves this dilemma by introducing value classes. A value class defines objects that lack identity. They are distinguished solely by the values of their fields, not by their address in memory.
To understand the impact of removing identity, consider how Java currently handles equality. If you compare two LocalDate instances representing the same date using the == operator, the comparison returns false because they are different physical objects on the heap.
An even more confusing example is the Integer wrapper class. To save memory, the JVM internally caches Integer instances for values below 128. As a result, == returns true for small identical integers, but false for identical values of 128 or higher. JEP 401 explicitly targets this "unwanted complexity" by migrating existing JDK classes, including Integer, to value classes.
// Traditional behavior with identity:
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true (due to caching)
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false (different heap identities)
// Under JEP 401 (Value Classes):
// Because identity is stripped, == compares field values directly.
// Both comparisons will consistently return true.
Without object identity, the JVM is free to optimize memory layouts. It can flatten value objects directly into arrays or containing classes, eliminating the pointer indirection and the object header overhead. An array of a million value-typed Point objects becomes a dense, contiguous block of memory—perfectly optimized for modern CPU caches.
The Developer Angle: Breaking Changes and the Long Road to Production
While the performance benefits of JEP 401 are incredibly exciting, developers must prepare for the deliberate breaking changes that come with removing object identity.
1. Synchronization Failures
Because value objects lack identity, they cannot be used for synchronization. If your legacy codebase synchronizes on wrapper types like Integer, that code will fail with an exception once those wrappers are migrated to value classes.
Integer lock = 42;
synchronized(lock) { // Will throw an exception in JDK 28+
// Critical section
}
2. The Migration Path and Preview Status
JDK 28 (targeted for March 2027) will introduce JEP 401 strictly as a preview feature, meaning it will be disabled by default. Developers will need to pass the --enable-preview flag to experiment with value classes.
Furthermore, Brian Goetz has cautioned that JEP 401 is only the first phase of Project Valhalla. While JEP 401 knocks down the barrier of object identity, achieving full value semantics requires giving up even more: namely, nullability and what Goetz terms "atomicity-safety-under-race" (ASUR).
Other languages, like C#, have navigated this via structs, but retrofitting this into Java's deeply entrenched object model without breaking backward compatibility is an extraordinary challenge. Consequently, Goetz warns that expecting Valhalla to exit preview in time for the JDK 29 Long-Term Support (LTS) release in September 2027 is "optimistic."
3. Impact on Other APIs
Valhalla's VM primitives are also the key blocker for other major Java initiatives. For instance, the Vector API, which allows developers to write data-parallel algorithms utilizing SIMD (Single Instruction, Multiple Data) instructions, cannot exit its incubation phase until it can rebase on Valhalla's underlying VM primitives.
A Generational Leap Worth the Wait
Project Valhalla is not a quick fix, nor is it a feature you will blindly enable in production the day JDK 28 drops. It is a long-term, highly calculated restructuring of Java's core engine.
By systematically dismantling the limitations of object identity, Valhalla ensures that Java remains highly competitive for modern, memory-intensive cloud workloads, AI infrastructure, and high-performance computing. The preview in JDK 28 is the first tangible step into this new era. It is time to start auditing your codebases for identity-sensitive operations on wrapper classes—the bridge to Valhalla is finally being built.
Sources & further reading
Mariana covers the fast-moving world of machine learning and generative AI, with a particular focus on how these technologies are reshaping development workflows. When she isn't stress-testing the latest foundation models, she's usually at a local hackathon.
Discussion 4
finally some love for java's performance
okay this is actually huge, @frontend_fae - the fact that value classes are coming as a preview in jdk 28 is going to be a total game changer for java's performance, can't wait to dive in and see the impact it has on our projects 🚀
@frontend_fae, totally agree - value classes should bring some serious performance boosts, but i'm also curious to see how this affects the overall java ecosystem, especially in terms of library support and compatibility 🙏
@opensource_maya, totally with you on that, library support will be key