Daily-It

개발, AI, 인프라, 자동화와 일상 IT 제품 후기를 직접 써보며 정리하는 기술 블로그입니다.

JDK 28 Project Valhalla key changes: how much Java performance improvement can we expect?

Summary

JDK 28 Project Valhalla is worth watching because it targets a long-standing Java performance tradeoff: developers often choose between meaningful small objects and primitive-like efficiency. The most important pieces to follow are JEP 401: Value Classes and Objects and JEP 402: Enhanced Primitive Boxing.

The practical expectation should be careful, not magical. Valhalla does not turn Java into Go or Rust. It may, however, make Java’s familiar object model cheaper for small value-like data such as Money, Point, IDs, ranges, timestamps, and metric points, especially when allocation, references, memory layout, and GC pressure matter.

Table of contents

Project Valhalla in one sentence

Project Valhalla is an attempt to combine Java’s object-oriented abstraction with performance characteristics that are closer to primitives.

The interesting part is not “one new syntax.” It is the direction: keep meaningful domain types while reducing some of the overhead that comes from ordinary identity-based objects.

Java is strong for structuring large systems and maintaining code over time. But in performance-sensitive paths, the gap between primitives and objects keeps showing up. An int is compact and fast, but it carries little domain meaning. A Money, Point, or UserId object is clearer, but creating many of them can add allocation, reference, and GC overhead.

JEP 401: Value Classes and Objects

JEP 401 introduces Value Classes and Objects (Preview). The core idea is to add objects without identity to the Java platform.

Ordinary Java objects have identity. Two objects with the same field values can still be different objects.

new Point(1, 2) == new Point(1, 2) // usually false for ordinary objects

A value object is different: the value matters more than identity. The JEP 401 direction can be illustrated like this.

value record Point(int x, int y) {}

Point p = new Point(17, 3);
Objects.hasIdentity(p);      // false
new Point(17, 3) == p;       // true

This is not just about how == behaves. If an object has no identity, the JVM has more room to optimize how it stores, copies, and lays out that value.

What value classes may mean for performance

The performance story mainly has three parts.

  • Less allocation pressure may be possible. If a value has no identity, the JVM has fewer reasons to allocate every instance as a separate heap object.
  • Memory layout may become more compact. Arrays and fields containing value-like objects can potentially be represented closer to the actual values instead of only arrays of references.
  • Domain modeling may cost less. Types such as Money, Point, Range, OrderId, EventTime, and MetricPoint can stay meaningful without always paying the full ordinary-object cost.

That does not mean every program automatically becomes faster. The real result depends on JVM implementation, JIT behavior, code shape, data size, and GC behavior. When the feature becomes available, it should be measured with the same discipline as any other performance change.

JEP 402: Enhanced Primitive Boxing

JEP 402, Enhanced Primitive Boxing (Preview), deals with the old split between primitive types and wrapper classes.

int       vs Integer
long      vs Long
double    vs Double

This split has always been awkward. Primitives are efficient, but they do not fit naturally into today’s generic APIs. Wrappers fit into generics, but they are objects and can carry object overhead. JEP 402 belongs to the broader Valhalla direction of making boxing and value-oriented objects more natural and efficient.

Will generics performance improve immediately?

This is where expectations need to be controlled. Many Java developers want List<int> to behave as efficiently as an int[]. But JEP 402 still describes generics as erasure-based.

Reasonable expectations:
- Reduce some of the gap between primitives and wrappers
- Open optimization opportunities around value classes
- Build a foundation for later specialized generics work

Expectations to avoid:
- Assuming List<int> immediately becomes int[]
- Assuming every generic-heavy code path becomes faster automatically

Valhalla is better understood as a staged evolution of Java’s type system and JVM, not a single switch that fixes all primitive generics performance problems.

What to expect in JDK 28, and what is still too early

The currently relevant expectation is that JEP 401 is being discussed as a JDK 28 target, but it is still a Preview feature. Preview means developers can try the feature and give feedback, while the specification and behavior can still change in later releases.

What is reasonable to expect around the JDK 28 timeframe:

  • Trying value class syntax and behavior in experiments
  • Getting a feel for identity-free objects
  • Reviewing which small value objects in your codebase might be candidates later
  • Benchmarking what the JVM actually optimizes in realistic code

What is too early:

  • Converting a large production service to value classes immediately
  • Replacing every DTO or record with a value class
  • Assuming generics performance is solved at once
  • Expecting Java to provide the same data-layout control as Go or Rust

What Java developers can prepare now

You do not need to change code today. A better first step is to identify where value-like modeling and performance currently conflict.

Money
Point
Range
UserId
OrderId
EventTime
MetricPoint

Look for places where code fell back to primitives only because object allocation was too expensive. Those places may become good experiment targets when value classes stabilize.

Also prepare benchmark criteria. For Valhalla, throughput alone is not enough. Allocation rate, memory footprint, and GC behavior should be measured together, preferably with a tool such as JMH when you test small hot paths.

Common points of confusion

“Value class means record, right?” Not quite. A record is concise syntax for a data carrier, but an ordinary record still has object identity. A value class or value record is about identity-free values.

“Can I use it broadly in production as soon as JDK 28 arrives?” Be careful. The relevant features are Preview. They are for learning, feedback, and experiments first, not a reason to rewrite an entire service immediately.

“Will this make Java as fast as Go or Rust?” That is the wrong comparison. Valhalla is about improving Java’s own object and primitive model. It can reduce a real weakness, but it does not change Java into a different language.

Conclusion

JDK 28 Project Valhalla matters because it touches one of Java’s oldest performance tradeoffs: meaningful objects versus primitive efficiency. JEP 401’s value classes and JEP 402’s enhanced primitive boxing point toward a Java where small value-like objects can be modeled more naturally with less overhead.

The right attitude is hopeful but measured. Do not plan a production rewrite around Preview features. Instead, learn the object-model change, identify value-like types in your own code, and prepare benchmarks so you can test the real effect when the tooling is ready.

Java Valhalla follow-ups

References

Original Korean version: This article is based on the Korean version and lightly adapted for English readers. Read the original Korean post.

Please show some love to Korean, too.