Java Next!

Amber to Valhalla, Leyden to Babylon

Developer Advocate

Java Team at Oracle

Lots to talk about!

Project Amber
Project Leyden
Project Valhalla
Project Babylon
Project Speedrun

Project Amber

Smaller, productivity-oriented Java language features

Profile:

Motivation

Some downsides of Java:

  • can be cumbersome

  • tends to require boilerplate

  • situational lack of expressiveness

Amber continuously improves that situation.

Delivered

Delivered

  • unnamed variables and patterns ㉒ (JEP 456)

  • multi-file source launcher ㉒ (JEP 458)

  • module imports ㉕ (JEP 511)

  • simplified main ㉕ (JEP 512)

  • flexible constructor bodies ㉕ (JEP 513)

Pattern Matching

Amber’s main thrust is pattern matching:

  • records

  • sealed types

  • improved switch

  • patterns

Sum > Parts

Amber Endeavors

Other endeavors and conversations:

  • primitive types in patterns (JEP 530)

  • deconstruction assignment (JEP draft)

  • derived record creation ("withers") (JEP 468)

  • deconstruction of classes (mails #1, #2)

  • serialization 2.0 (talks #1, #2)

  • concise method bodies (JEP draft)

Primitive Patterns

Rounds out the language
by allowing primitives in patterns:

int x = 16_777_217;
if (x instanceof float f)
	// lossless; use `f`
else
	// lossy

"Withers"

Deriving new record instances
from existing ones:

record Point(int x, int y) { }

var p0 = new Point(0, 0);
var p1 = p0 with { x = 1; };

(Strawman syntax.)

Deconstructible Classes

// ↙ CLASS        ↙ state description
class Point(int x, int y) {

	// fields
	// constructors
	//     if one matches the state description,
	//     the class can be "withered"
	// accessors
	// equals, hashCode, etc.

}

(Strawman syntax.)

Project Amber

  • makes Java more expressive

  • reduces amount of code

  • makes us more productive

Timeline

JDK 21:

  • records & sealed types

  • pattern matching basics

  • text blocks

  • single-file source launcher

JDK 25:

  • unnamed variables and patterns

  • multi-file source launcher

  • simplified main & module imports

  • flexible constructor bodies

Timeline

Current work:

  • primitive types in patterns (JEP 530)

  • deconstruction & reconstruction

Deeper Dives

Project Leyden

Faster startup, shorter time to peak performance, smaller footprint

Profile:

Motivation

Java has really good peak performance,
but also tends to have:

  • slow startup time

  • slow warmup time

Startup & Warmup

Early work by the runtime:

  • class loading

  • callsite linkage

  • constant pool resolution

  • interpretation

  • profile gathering

  • JIT compilation (C1, C2)

Can we shift this work?

Shifting Computation

Java already shifts computation:

  • compile-time constant folding

  • class loading

  • garbage collection

  • out-of-order execution

  • …​

Let’s shift more computation ahead of time!

Dynamic Java

Early work depends on:

  • class/module path content

  • command line options,
    particularly module options

  • run-time hardware and behavior

Only known during execution.

How to AOT everything?

Enter AOTCache

Leyden introduces AOTCache:

  • observe JVM

  • capture decisions in AOTCache
    (expansion of CDS Archive)

  • use as "initial state" during future run

  • fall back to live observation/optimization
    if necessary and possible

AOT workflow

# training run (⇝ profile)
$ java -XX:AOTMode=record
       -XX:AOTConfiguration=app.aotconf
       -cp app.jar com.example.App ...
# assembly phase (profile ⇝ AOTCache)
$ java -XX:AOTMode=create
       -XX:AOTConfiguration=app.aotconf
       -XX:AOTCache=app.aot
       -cp app.jar
# production run (AOTCache ⇝ performance)
$ java -XX:AOTCache=app.aot
       -cp app.jar com.example.App ...

AOT workflow

Shortcut for most cases:

# training run (⇝ AOTCache)
$ java -XX:AOTCacheOutput=app.aot
       -cp app.jar com.example.App ...
# production run (AOTCache ⇝ performance)
$ java -XX:AOTCache=app.aot
       -cp app.jar com.example.App ...

(Open to further improvements.)

Class loading & linking

Improve startup time by making the classes of an application instantly available, in a loaded and linked state, when the HotSpot JVM starts.

Spring PetClinic benchmarks:

  • up to ~40% startup time reduction

  • AOT cache size of ~130 MB

Method profiling

Improve warmup time by making method-execution profiles from a previous run of an application instantly available, when the HotSpot Java Virtual Machine starts.

Benchmark of a 100_000x loop over a simple stream:

  • ~20% run time reduction

  • AOT cache size increased by ~2.5%

Streaming cached objects

Making it possible to load cached Java objects sequentially into memory from a neutral, GC-agnostic format.

  • allows use of any garbage collector

  • does not block when initializing heap

  • takes longer for warm starts and
    requires a CPU core

(Note: The cache contains no application instances.)

Code Compilation

Improve startup and warmup time by making optimized native code for an application instantly available when the HotSpot JVM starts.

Benchmarks with javac:

  • ~15% startup time reduction

  • ~75% fewer warmup iterations

AOT limitations

  • for code compilation: AArch64 or x64

  • training vs production:

    • same JDK release / architecture / OS

    • for code compilation: same CPU features & GC

    • consistent class path

    • consistent module options

  • limited use of JVMTI agents

Otherwise, unsuitable portions are ignored.

AOT everything

Leyden’s EA AOTs more:

  • constant resolution

  • dynamic proxies

  • reflection data

  • unfound classes

Benchmarks show ~70% startup time reduction.

Project Leyden

  • improves Java’s overall footprint

  • focusses on startup/warmup time
    by caching early JVM work

  • may explore stricter constraints
    for more aggressive optimization

Timeline

JDK 25:

JDK 26:

JDK 28:

Current work

  • expand AOTCache

  • allow tradeoff between
    portability and peak performance

  • iterative training

  • better inspectability of training data

Deeper Dives

Project Valhalla

Advanced Java VM and Language feature candidates

Profile:

Motivation

Java has a split type system:

  • primitives

  • classes

We can only create classes, but:

  • have identity

  • have references

Identity

All classes come with identity:

  • extra memory for header

  • mutability

  • locking, synchronization, etc.

But not all custom types need that!

References

All instances come as references:

  • memory access indirection

  • nullability

But not all code needs that!

Project Valhalla

Valhalla’s goal is to unify the type system.

Primary mechanism: value classes.

Potential follow-up work:

  • null-restriction

  • specialized generics

  • universal generics

  • type classes

JDK value classes

In package java.lang :

Integer, Long, Float, Double, Byte, Short, Character, Boolean, Number, Record

In package java.util :

Optional, OptionalInt, OptionalLong, OptionalDouble

In package java.time :

LocalDate, LocalTime, LocalDateTime, ZonedDateTime, OffsetTime, OffsetDateTime, Duration, Instant, Period, Year, YearMonth, MonthDay

In package java.time.chrono :

MinguoDate, HijrahDate, JapaneseDate, ThaiBuddhistDate

Custom value classes

value class ComplexNumber {

	private double real;
	private double imaginary;

	// constructor, etc.
}

Codes (almost) like a class - exceptions:

  • class and fields are implicitly final

  • superclasses are limited

Value class behavior

No identity:

  • "identity" check == compares by state

  • some operations throw exceptions

  • (null is the default value)

Benefits:

  • guaranteed immutability

  • more expressiveness

  • more optimizations

Reference Scalarization

When passing objects to or from a method,
the runtime generally references heap objects.

Tracking identity:

  • required for identity objects
    unless escape analysis shows it isn’t

  • never needed for value objects

⇝ The runtime can load value object fields once
and use the stack to pass them.

Flattening

Reference flattening:

  • encode object’s fields in reference

  • requires extra bit for nullity

  • limited by atomic writes (⇝ 64 bits)

  • limited by type information

Improve flattening

Flattening would be more applicable with:

  • performant 128-bit atomic writes

  • language-level atomicity control

  • language-level nullity information

  • generic specialization

Null-restriction

Details are in flux, but possibly:

// number can't be null
ComplexNumber! number = // ...

Generic specialization

Value classes can be type parameters:

List<ComplexNumber> numbers = new ArrayList<>();

But if ArrayList<ComplexNumber> is backed by Object[],
it will still be avoided in many cases.

Specialized generics would enable ComplexNumber[],
which allows the JVM to flatten references.

Universal generics

To completely heal the rift, List<int> would be great!

Ideally, int is just the legacy version of Integer!.

⇝ List<int> just works.

Emergent performance

Don’t create a value class in order to get performance.

Instead:

  • "Is the type value-ish?" ⇝ value class

  • "Is no null needed?" ⇝ restrict nullness

  • "Do I control concurrency" ⇝ relax atomicity

Performance emerges from domain decisions!

Type classes

For value classes to feel like primitives,
we need to use them with operators.

Maybe (!) Java will let us define common operations
for suitale types (with type classes):

var one = new ComplexNumber(1, 0);
var i = new ComplexNumber(0, 1);

var x = one + i; // maybe
var y = one * i; // maybe
var z = one $ i; // NO!

Project Valhalla

Value classes, null-restriction, and specialized generics:

  • fewer trade-offs between
    design and performance

  • no more manual specializations

  • better performance

  • can express design more clearly

  • more robust APIs

Makes Java more expressive and performant.

Timeline

Value classes are a preview feature in JDK 28.

Everything else is TBD.

Deeper Dives

Deeper Dives

Project Babylon

Extend the reach of Java to foreign programming models such as SQL, differentiable programming, machine learning models, and GPUs

Profile:

Motivation

Java is adjacent to other programmable systems:

  • GPUs and FPGAs

  • SQL databases

  • differentiable functions

Allow programming them with Java code.

Approach

Don’t adapt to each realm in a separate project.

Instead:

  • make Java code accessible

  • provide API to read and transform it

  • let ecosystem provide adaptions

Code Reflection

Babylons’s central mechanism is code reflection:

  • enhancement of "regular" reflection

  • reaches down into methods/lambdas

  • symbolic representation of (Java) code

These are called code models.

NIH?

Abstract syntax tree:

  • constructed during compilation

  • closely aligned with Java grammar

  • too much syntactic info

Bytecode:

  • created by compiler

  • specified by JVM Specification

  • too little important info

Code Models

The code model design is heavily influenced by the design of data structures used by many modern compilers to represent code. These data structures are commonly referred to as Intermediate Representations (IRs). The design is further influenced by Multi-Level Intermediate Representation (MLIR), a sub-project of the LLVM Compiler Infrastructure project.

Code Models

Identify code (e.g. with annotation):

@CodeReflection
static double sub(double a, double b) {
   return a - b;
}

Then:

  • compiler creates code model

  • stored in class files

  • accessible via reflection API

  • can be transformed by Java code

Transforming Code Models

"Direct" GPU programming:

  • transform to GPU kernels (OpenCL C or CUDA C)

  • compile with GPU-specific toolchain

Triton-style:

  • offer class Triton with static methods

  • transform to Triton code model

  • compile with Triton toolchain

Triton

@CodeReflection
static void add_kernel2(
		Ptr x, Ptr y, Ptr result, int n, int size) {
    var pid = Triton.programId(0);
    var block_start = pid * size;
    var range = Triton.arange(0, size);
    var offsets = Triton.add(block_start, range);
    var mask = Triton.compare(
		offsets, n, Triton.CompareKind.LessThan);
    var x = Triton.load(Triton.add(x, offsets), mask);
    var y = Triton.load(Triton.add(y, offsets), mask);
    var output = Triton.add(x, y);
    Triton.store(
		Triton.add(result, offsets), output, mask);
}

Project Babylon

  • introduces code reflection & code models

  • allows their transformation

  • expands Java to foreign programming models

  • spearheads Java-on-GPU efforts (HAT)

Timeline

🤷🏾‍♂️

(Code reflection prototype is being polished for incubation.)

Deeper Dives

Project Speedrun

Not actually a project

Project Loom

Support easy-to-use, high-throughput, lightweight concurrency and new programming models

Deliverables:

  • virtual threads

  • scoped values

  • structured concurrency

Timeline

JDK 21:

  • virtual threads finalize (JEP 444)

  • structured concurrency previews (JEP 453)

  • scoped values preview (JEP 446)

JDK 25:

  • object monitors don’t pin virtual threads (JEP 491)

  • structured concurrency preview revamp (JEP 499)

  • scoped values finalize (JEP 506)

Timeline

JDK 26:

JDK 27:

  • structured concurrency in 7th preview (JEP 533)

Current work:

  • finalize structured concurrency

  • improve lock info in thread dumps

Deeper Dives

Project Panama

Interconnecting JVM and native code

Deliverables:

  • foreign function & memory API

  • vector API

Timeline

JDK 21:

  • foreign APIs in 3rd preview (JEP 442)

  • vector API in 6th incubation (JEP 448)

JDK 25:

JDK 27:

  • vector API in 12th incubation (JEP 537),
    waiting for Valhalla’s value types

Deeper Dives

Foreign APIs:

Vector API:

Project Lilliput

Explore techniques to downsize Java object headers in the Hotspot JVM from 128 bits to 64 bits or less

Deliverables:

  • compact object headers (⇝ 64 bits)

  • even more compact object headers (⇝ 32 bits)

Timeline

JDK 25:

JDK 27:

  • compact object headers by default (JEP 534)

Maybe:

Deeper Dives

Project Detroit

Provide implementations of javax.script
for JavaScript based on Chrome V8 and
for Python based on CPython.

No deliverables yet.

Timeline

2026:

  • project reestablished

  • early prototypes are promising

Deeper Dives

So long…​

37% off with
code fccparlog

bit.ly/the-jms

More

Slides at slides.nipafx.dev
⇜ Get my book!

Follow Nicolai

nipafx.dev
🦋 🐘 /nipafx

Follow Java

inside.java // dev.java
/java    //    /openjdk

Image Credits

Image Credits