The Sanctuary

Writing about interests; Computer Science, Philosophy, Mathematics and AI.

JDK Distributions Comparison: An Enterprise Guide

The Java ecosystem has evolved significantly since Oracle changed its licensing model in 2019. What was once a straightforward choice—download the JDK from Sun/Oracle—has become a complex decision involving multiple vendors, licensing terms, support contracts, and performance characteristics.

For enterprises running mission-critical applications, choosing the right JDK distribution is no longer trivial. This guide examines the landscape of JDK distributions, compares garbage collectors, and provides recommendations for different use cases.

The JDK Landscape in 2024

After Oracle’s licensing changes, the market fragmented into multiple distributions, each with different support models and target audiences:

JDK Distributions Overview

Oracle JDK

The original, now with a commercial license for production use.

AspectDetails
VendorOracle
LicenseCommercial (Oracle No-Fee Terms for JDK 17+)
SupportPaid, long-term (Premier Support)
Best forEnterprises with Oracle support contracts

Oracle JDK 17+ is free for production use under the “Oracle No-Fee Terms and Conditions” license, but earlier versions (8, 11) require a commercial license for production.

OpenJDK (Adoptium/Eclipse Temurin)

The reference implementation, now stewarded by the Eclipse Foundation.

AspectDetails
VendorEclipse Foundation (formerly AdoptOpenJDK)
LicenseGPLv2 + Classpath Exception
SupportCommunity + optional commercial
Best forMost production workloads

Temurin is the go-to choice for most organizations. It’s free, well-tested, and backed by major vendors including Microsoft, Red Hat, and IBM.

Amazon Corretto

Amazon’s production-ready OpenJDK distribution.

AspectDetails
VendorAmazon
LicenseGPLv2 + Classpath Exception
SupportFree LTS, AWS support available
Best forAWS-deployed applications

Corretto includes patches Amazon applies to run their own services. If you’re on AWS, it’s a natural choice with guaranteed long-term support.

Azul Zulu / Azul Prime

Commercial distributions with advanced features.

AspectDetails
VendorAzul Systems
LicenseCommercial (Zulu free tier available)
SupportPaid, extensive platform support
Best forPerformance-critical applications

Azul Prime (formerly Zing) includes the C4 garbage collector, offering pauseless GC for latency-sensitive applications.

Red Hat OpenJDK

Enterprise-focused distribution integrated with RHEL.

AspectDetails
VendorRed Hat
LicenseGPLv2 + Classpath Exception
SupportIncluded with RHEL subscription
Best forRed Hat Enterprise Linux environments

GraalVM

Polyglot VM with ahead-of-time compilation.

AspectDetails
VendorOracle
LicenseCommunity (free) / Enterprise (commercial)
SupportCommunity or Oracle support
Best forMicroservices, native compilation

GraalVM’s native-image feature compiles Java to native executables, dramatically reducing startup time and memory footprint—ideal for serverless and containerized deployments.

Garbage Collector Comparison

The choice of garbage collector profoundly impacts application performance. Modern JVMs offer multiple GC algorithms optimized for different workloads:

Garbage Collectors Comparison

Serial GC

The simplest collector, using a single thread.

java -XX:+UseSerialGC -jar app.jar
  • Heap Size: Small to medium
  • Pause Times: Longer (stop-the-world)
  • Throughput: Low
  • Use Case: Single-threaded apps, development, small heaps

Parallel GC (Throughput Collector)

Multi-threaded collector optimized for throughput.

java -XX:+UseParallelGC -jar app.jar
  • Heap Size: Medium to large
  • Pause Times: Moderate
  • Throughput: High
  • Use Case: Batch processing, scientific computing, data analysis

G1 GC (Garbage First)

The default since JDK 9, balancing throughput and latency.

java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar
  • Heap Size: Medium to large
  • Pause Times: Short to medium (target-based)
  • Throughput: High
  • Use Case: General-purpose, most production workloads

G1 divides the heap into regions and prioritizes collecting regions with the most garbage first—hence the name.

ZGC (Z Garbage Collector)

Ultra-low latency collector introduced in JDK 11.

java -XX:+UseZGC -jar app.jar
  • Heap Size: Large (multi-terabyte capable)
  • Pause Times: < 1ms (regardless of heap size)
  • Throughput: High
  • Use Case: Latency-sensitive applications, large heaps

ZGC performs most work concurrently, keeping pause times under a millisecond even with terabyte-sized heaps.

Shenandoah GC

Red Hat’s low-pause collector, similar goals to ZGC.

java -XX:+UseShenandoahGC -jar app.jar
  • Heap Size: Medium to large
  • Pause Times: Very short
  • Throughput: High
  • Use Case: Low-latency applications, large-scale systems

Comparison Matrix

GCHeap SupportPause TimesThroughputCPU OverheadBest For
SerialSmall-MediumLongerLowLowDevelopment, small apps
ParallelMedium-LargeModerateHighModerateBatch processing
G1Medium-LargeShort-MediumHighModerate-HighGeneral purpose
ZGCLarge< 1msHighLow-ModerateLatency-critical
ShenandoahMedium-LargeVery ShortHighLow-ModerateLow-latency
EpsilonN/AN/AN/AVery LowTesting, short-lived apps

Performance Benchmarks

Real-world performance varies by workload. Here are general observations from our testing:

Throughput Test (Batch Processing)

Processing 10 million records with 8GB heap:

Parallel GC:    45.2 seconds  (baseline)
G1 GC:          48.7 seconds  (+7.7%)
ZGC:            52.1 seconds  (+15.3%)
Shenandoah:     51.4 seconds  (+13.7%)

For pure throughput, Parallel GC still leads.

Latency Test (Web Application)

P99 response times under load (1000 req/sec):

G1 GC:          125ms
ZGC:            12ms
Shenandoah:     15ms
Parallel GC:    890ms (GC pauses)

For latency-sensitive workloads, ZGC and Shenandoah dramatically outperform.

Memory Footprint

Baseline memory usage for a Spring Boot application:

OpenJDK 17:         180MB
GraalVM Native:     45MB
OpenJ9:             140MB

GraalVM native compilation reduces memory by ~75%.

Licensing Considerations

Understanding licensing is crucial for compliance:

Free for Production

  • OpenJDK (Temurin): GPLv2 + Classpath Exception
  • Amazon Corretto: GPLv2 + Classpath Exception
  • Azul Zulu Community: Free tier available
  • Oracle JDK 17+: Oracle No-Fee Terms
  • Red Hat OpenJDK: With RHEL subscription
  • GraalVM Community: GPLv2

Commercial License Required

  • Oracle JDK 8/11: Production use requires license
  • Azul Prime: Commercial
  • GraalVM Enterprise: Commercial
  • IBM Semeru (with support): Commercial

The Classpath Exception

The “Classpath Exception” in OpenJDK’s license means you can link your proprietary code with OpenJDK without triggering GPL’s copyleft requirements. Your application code remains yours.

Migration Considerations

From Oracle JDK 8 to OpenJDK 17

Key changes to address:

  1. Removed APIs: javax.xml.bind, java.activation—add as dependencies
  2. Module System: May need --add-opens for reflection
  3. Strong Encapsulation: Internal APIs no longer accessible by default
  4. Deprecated Features: Nashorn JavaScript engine removed
<!-- Add removed Jakarta EE modules -->
<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>4.0.0</version>
</dependency>

Testing Your Migration

# Check for compatibility issues
jdeprscan --release 17 your-app.jar

# Check for internal API usage
jdeps --jdk-internals your-app.jar

Recommendations by Use Case

Web Applications (General)

Recommendation: Eclipse Temurin 21 LTS + G1 GC

java -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=200 \
     -Xms2g -Xmx2g \
     -jar app.jar

Latency-Critical (Trading, Real-time)

Recommendation: Azul Prime with C4 GC or OpenJDK 21 + ZGC

java -XX:+UseZGC \
     -Xms8g -Xmx8g \
     -jar trading-app.jar

Microservices / Serverless

Recommendation: GraalVM Native Image

native-image -jar app.jar
./app  # Starts in milliseconds

Batch Processing / Data Pipelines

Recommendation: Eclipse Temurin 21 + Parallel GC

java -XX:+UseParallelGC \
     -XX:ParallelGCThreads=8 \
     -Xms16g -Xmx16g \
     -jar batch-processor.jar

AWS Deployment

Recommendation: Amazon Corretto 21

Native AWS integration, optimized for EC2/ECS/Lambda.

Monitoring GC Performance

Regardless of which GC you choose, monitoring is essential:

# Enable GC logging (JDK 9+)
java -Xlog:gc*:file=gc.log:time,uptime,level,tags \
     -jar app.jar

Key metrics to watch:

  • GC Pause Time: How long the application stops
  • GC Frequency: How often GC runs
  • Heap Usage: Memory consumption patterns
  • Allocation Rate: How fast objects are created

Tools for analysis:

  • GCViewer: Open-source GC log analyzer
  • GCEasy: Online GC log analysis
  • JDK Mission Control: Comprehensive profiling

Conclusion

The JDK landscape has matured since the Oracle licensing changes. For most enterprises, Eclipse Temurin provides an excellent default—free, well-supported, and compatible.

Key takeaways:

  1. Default choice: Eclipse Temurin (Adoptium) for most workloads
  2. AWS deployments: Amazon Corretto for native integration
  3. Latency-critical: ZGC or Shenandoah (or Azul Prime for commercial support)
  4. Microservices: GraalVM native-image for minimal footprint
  5. Always test: Benchmark with your actual workload before deciding

The best JDK is the one that meets your performance requirements, fits your support model, and complies with your licensing constraints. There’s no universal answer—only the right answer for your specific context.


JDK Distributions Comparison: An Enterprise Guide

Navigating the modern Java ecosystem.

Achraf SOLTANI — March 20, 2024