JDK 26’s Position
JDK 26, released on March 17, 2026, is a non-LTS release containing 10 JEPs. While the JEP count is lower than JDK 24 (24 JEPs), it includes practically impactful features: HTTP/3 support (JEP 517) and G1 GC throughput improvement (JEP 522). Additionally, Prepare to Make Final Mean Final (JEP 500) is noteworthy as it reveals Java’s long-term language direction.
HTTP/3 for HttpClient API (JEP 517, Final)
The HttpClient introduced in JDK 11 finally supports HTTP/3. HTTP/3 uses the QUIC protocol instead of TCP, offering benefits like Head-of-Line Blocking resolution (packet loss doesn’t affect other streams), faster connection establishment (0-RTT), and maintaining connections across network switches (Connection Migration).
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class Http3Demo {
public static void main(String[] args) throws Exception {
// Create an HttpClient with HTTP/3 support
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_3) // Specify HTTP/3
.connectTimeout(Duration.ofSeconds(10))
.build();
// Create an HTTP/3 request
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://www.google.com"))
.GET()
.build();
// Send request and receive response
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println("=== HTTP/3 Response Info ===");
System.out.println("Status code: " + response.statusCode());
System.out.println("Protocol: " + response.version());
System.out.println("Response size: " + response.body().length() + " chars");
// Example output:
// === HTTP/3 Response Info ===
// Status code: 200
// Protocol: HTTP_3
// Response size: 14523 chars
// Print headers
response.headers().map().forEach((key, values) -> {
if (key.startsWith("content") || key.startsWith("server")) {
System.out.println(key + ": " + values);
}
});
}
}
An important note when using HTTP/3: if the server doesn’t support HTTP/3, it automatically falls back to HTTP/2 or HTTP/1.1. Simply changing HttpClient.Version.HTTP_2 to HTTP_3 in existing code upgrades it, with no server compatibility concerns.
| Protocol | Transport Layer | Key Features |
|---|---|---|
| HTTP/1.1 | TCP | Sequential request/response |
| HTTP/2 | TCP | Multiplexing, header compression, server push |
| HTTP/3 | QUIC (UDP) | HoL Blocking resolved, 0-RTT, connection migration |
G1 GC Throughput Improvement (JEP 522)
JDK 26 improves throughput of the default G1 GC by up to 15%. Since G1 has been the default GC since JDK 9 and is used by most Java applications, this improvement applies to virtually all projects without any configuration changes.
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class G1ThroughputDemo {
public static void main(String[] args) {
// G1 GC throughput test: simulating mass object allocation and deallocation
// Run: java -verbose:gc G1ThroughputDemo
Random random = new Random(42);
List<byte[]> liveObjects = new ArrayList<>();
int totalAllocated = 0;
long start = System.nanoTime();
for (int cycle = 0; cycle < 100; cycle++) {
// Object allocation: create byte arrays of various sizes
for (int i = 0; i < 1000; i++) {
int size = random.nextInt(1024, 65536); // 1KB ~ 64KB
liveObjects.add(new byte[size]);
totalAllocated++;
}
// Object deallocation: remove 70% to trigger GC (Weak Generational Hypothesis simulation)
int removeCount = (int) (liveObjects.size() * 0.7);
for (int i = 0; i < removeCount; i++) {
liveObjects.remove(liveObjects.size() - 1);
}
}
long elapsed = (System.nanoTime() - start) / 1_000_000;
System.out.println("=== G1 GC Throughput Test ===");
System.out.println("Total objects allocated: " + totalAllocated);
System.out.println("Surviving objects: " + liveObjects.size());
System.out.println("Time elapsed: " + elapsed + "ms");
System.out.println();
System.out.println("JDK 26 G1 improvements:");
System.out.println(" - Up to 15% throughput improvement");
System.out.println(" - Remembered Set optimization");
System.out.println(" - Write Barrier efficiency gains");
// Example output:
// === G1 GC Throughput Test ===
// Total objects allocated: 100000
// Surviving objects: 811
// Time elapsed: 2340ms
//
// JDK 26 G1 improvements:
// - Up to 15% throughput improvement
// - Remembered Set optimization
// - Write Barrier efficiency gains
}
}
The G1 throughput improvement was achieved through Remembered Set management and Write Barrier optimization. The Remembered Set is a data structure that tracks pointers from the Old generation to the Young generation. By reducing its management cost, application threads gain more CPU time.
AOT Object Caching with Any GC (JEP 516)
The AOT class loading introduced in JDK 24 (JEP 483) has taken another step forward. JDK 26 makes AOT object caching compatible with all GCs. Previously, AOT cache was only available with specific GCs, but now G1, ZGC, Shenandoah, Serial, and Parallel GCs all benefit from AOT caching.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class AotCachingDemo {
// AOT caching effect simulation
// Run 1: java -XX:AOTCache=app.aotcache -XX:AOTMode=record AotCachingDemo
// Run 2: java -XX:AOTCache=app.aotcache -XX:AOTMode=on AotCachingDemo
public static void main(String[] args) {
long startTime = System.nanoTime();
// Typical application initialization code
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String now = LocalDateTime.now().format(formatter);
// Operations requiring class loading + linking
var list = java.util.stream.IntStream.range(0, 1000)
.boxed()
.toList();
long elapsedMs = (System.nanoTime() - startTime) / 1_000_000;
System.out.println("=== AOT Object Caching Effect ===");
System.out.println("Current time: " + now);
System.out.println("Initialization time: " + elapsedMs + "ms");
System.out.println("List size: " + list.size());
System.out.println();
System.out.println("JDK 26 AOT changes:");
System.out.println(" - AOT cache available with all GCs");
System.out.println(" - G1, ZGC, Shenandoah, Serial, Parallel all supported");
System.out.println(" - Reduced class loading/linking cost on restart");
// Example output:
// === AOT Object Caching Effect ===
// Current time: 2026-04-07 14:30:00
// Initialization time: 45ms
// List size: 1000
//
// JDK 26 AOT changes:
// - AOT cache available with all GCs
// - G1, ZGC, Shenandoah, Serial, Parallel all supported
// - Reduced class loading/linking cost on restart
}
}
AOT caching is particularly effective in microservices environments. Since containers must re-load classes and go through JIT warmup on every restart, caching mitigates the Cold Start problem.
Other Notable JEPs
Prepare to Make Final Mean Final (JEP 500): The first step in a long-term project to strengthen the meaning of the final keyword. Currently, final fields can be modified through reflection or Unsafe, and this will be gradually blocked. Frameworks like Hibernate and Jackson use patterns that modify final fields via reflection, so library compatibility should be checked.
Applet API Complete Removal (JEP 504): The Applet API, which has existed since Java 1.0 in 1995, is completely removed. The java.applet package and related classes are deleted. Since it was already deprecated in JDK 9, virtually no projects should be affected. The official retirement of a 30-year legacy.
GC Evolution Timeline from JDK 23-26
The GC-related changes from JDK 23 to 26 show a clear direction:
| Version | GC Change |
|---|---|
| JDK 23 | ZGC Generational mode becomes default |
| JDK 24 | ZGC Non-Generational mode removed, G1 Late Barrier Expansion |
| JDK 25 | Compact Object Headers finalized (heap 22% down), Shenandoah Generational finalized |
| JDK 26 | G1 throughput 15% up, AOT cache all GCs supported |
Three axes — consolidation toward generational GC, object header compression, and G1 optimization — are progressing simultaneously, with JDK 26 bearing the fruits of this direction.
Practical Tips
| Feature | Status | Key Points |
|---|---|---|
| HTTP/3 | Final | HttpClient.Version.HTTP_3, auto-fallback |
| G1 Throughput Boost | Final | Up to 15% throughput improvement, no config changes needed |
| AOT Cache Expansion | Final | AOT object caching with all GCs |
| Final Keyword Hardening | Final | Gradual blocking of final field modification via reflection |
| Applet API Removal | Final | java.applet package completely removed |
The highest-impact change in JDK 26 is the G1 GC throughput improvement. Since most Java applications use G1 as their default, upgrading JDK alone yields performance improvements. HTTP/3 support also makes a meaningful difference in high-latency environments or mobile networks, so if your project uses HttpClient, it’s worth trying by changing just the version option.