Most of major enhancements in Java 12, which is released in March 2019 are in JVM area. The most interesting update in the Java language is simplified switch statements. But unfortunately it’s a preview language feature, so it’s not finalized and not enabled by default.

Here my Oracle JDK version:

$ java -version
java version "12" 2019-03-19
Java(TM) SE Runtime Environment (build 12+33)
Java HotSpot(TM) 64-Bit Server VM (build 12+33, mixed mode, sharing)

Here my AdoptOpenJDK (HotSpot JVM) version:

$ java -version
openjdk version "12" 2019-03-19
OpenJDK Runtime Environment AdoptOpenJDK (build 12+33-201903200952)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 12+33-201903200952, mixed mode, sharing)

And here my AdoptOpenJDK (OpenJ9 JVM) version:

$ java -version
openjdk version "12" 2019-03-19
OpenJDK Runtime Environment AdoptOpenJDK (build 12+32-201903201138)
Eclipse OpenJ9 VM AdoptOpenJDK (build master-7a8bf1efc, JRE 12 Windows 10 amd64-64-Bit Compressed References 20190320_31 (JIT enabled, AOT enabled)
OpenJ9   - 7a8bf1efc
OMR      - dbcc5732
JCL      - bb38f8aaac based on jdk-12+33)

This article is a summary of each JEP as documented for JDK 12.

JEP 189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)

JEP 189 in summary is to add a new garbage collection (GC) algorithm named Shenandoah which reduces GC pause times by doing evacuation work concurrently with the running Java threads. Pause times with Shenandoah are independent of heap size, meaning you will have the same consistent pause times whether your heap is 200 MB or 200 GB. The Shenandoah algorithm is described in depth in this PPPJ2016 paper.

As experimental feature, Shenandoah will require -XX:+UnlockExperimentalVMOptions in the command line. The Shenandoah build system disables the build on unsupported configurations automatically. Downstream builders may choose to disable building Shenandoah with --with-jvm-features=-shenandoahgc on otherwise supported platforms.

To enable/use Shenandoah GC, the following JVM options will be needed:

-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC

Please see the Shenandoah wiki page for more information on how to setup and tune Shenandoah GC.

However, using Oracle JDK 12 I'm getting following error:

$ java -XX:+UseShenandoahGC
Error: VM option 'UseShenandoahGC' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.
Error: The unlock option must precede 'UseShenandoahGC'.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

$ java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC
Error occurred during initialization of VM
Option -XX:+UseShenandoahGC not supported

JEP 230: Microbenchmark Suite

JEP 230 add a basic suite of microbenchmarks to the JDK source code, and make it easy for developers to run existing microbenchmarks and create new ones. Goals:

  • Based on the Java Microbenchmark Harness (JMH)
  • Stable and tuned benchmarks, targeted for continuous performance testing
    • A stable and non-moving suite after the Feature Complete milestone of a feature release, and for non-feature releases
    • Support comparison to previous JDK releases for applicable tests
  • Simplicity
    • Easy to add new benchmarks
    • Easy to update tests as APIs and options change, are deprecated, or are removed during development
    • Easy to build
    • Easy to find and run a benchmark
  • Support JMH updates
  • Include an initial set of around a hundred benchmarks in the suite

JEP 325: Switch Expressions (Preview)

JEP 325 extends the switch statement so that it can be used as either a statement or an expression, and that both forms can use either a "traditional" or "simplified" scoping and control flow behavior. These changes will simplify everyday coding, and also prepare the way for the use of pattern matching (JEP 305) in switch. This will be a preview language feature.

Two main changes to switch in starting from Java 12:

  • Introduction of case L -> syntax that removes the need for break statements, because only the statements next to -> is executed.
  • switch can be an expression, so it can have a value, or it can return a value.
public class JEP325SwitchCase {

    public static void main(String[] args) {
        System.out.println("Using Standard Switch Case");
        System.out.println("Using New Switch Case:");
     * Function with 'standard' switch
     * @param day
     * @return String dayName
    public static String getDayName(int day) {
        String dayName;
        switch (day) {
            case 1:
                dayName = "Monday";
            case 2:
                dayName = "Tuesday";
            case 3:
                dayName = "Wednesday";
            case 4:
                dayName = "Thursday";
            case 5:
                dayName = "Friday";
            case 6:
                dayName = "Saturday";
            case 7:
                dayName = "Sunday";
                dayName = "Invalid day";
        return dayName;
     * Function with 'new-style' switch
     * @param day
     * @return String dayName
    public static String getNewDayName(int day) {
        return switch (day) {
            case 1 -> "Monday";
            case 2 -> "Tuesday";
            case 3 -> "Wednesday";
            case 4 -> "Thursday";
            case 5 -> "Friday";
            case 6 -> "Saturday";
            case 7 -> "Sunday";
            default -> "Invalid day";

Using Standard Switch Case
Invalid day
Using New Switch Case:
Invalid day

JEP 334: JVM Constants API

JEP 334 introduced an API to model nominal descriptions of key class-file and run-time artifacts, in particular constants that are loadable from the constant pool. This JEP was originally a sub-feature of JEP 303 (Intrinsics for the LDC and INVOKEDYNAMIC Instructions). JEP 303 now depends upon this JEP.

A family of value-based symbolic reference (JVMS 5.1) types is defined in the new package java.lang.invoke.constant and capable of describing each kind of loadable constant. A symbolic reference describes a loadable constant in purely nominal form, separate from class loading or accessibility context. Some classes can act as their own symbolic references (e.g., String); for linkable constants we define a family of symbolic reference types (ClassDesc, MethodTypeDesc, MethodHandleDesc, and DynamicConstantDesc) that contain the nominal information to describe these constants.

A draft snapshot of the API specification can be found here, and more information on its relationship with the features in JEP 303 can be found in this companion document.

JEP 340: One AArch64 Port, Not Two

JEP 340 remove all of the sources related to the arm64 port while retaining the 32-bit ARM port and the 64-bit aarch64 port. Removing this port will allow all contributors to focus their efforts on a single 64-bit ARM implementation, and eliminate the duplicate work required to maintain two ports.

JEP 341: Default CDS Archives

JEP 341 enhanced the JDK build process to generate a class data-sharing (CDS) archive, using the default class list, on 64-bit platforms. Goals:

  • Improve out-of-the-box startup time
  • Eliminate the need for users to run -Xshare:dump to benefit from CDS

JEP 344: Abortable Mixed Collections for G1

JEP 344 make G1 mixed collections abortable if they might exceed the pause target.

If G1 discovers that the collection set selection heuristics repeatedly select the wrong number of regions, switch to a more incremental way of doing mixed collections: split the collection set into two parts, a mandatory and an optional part. The mandatory part comprises parts of the collection set that G1 cannot process incrementally (e.g., the young regions) but can also contain old regions for improved efficiency. This may, e.g., be 80% of the predicted collection set. The remaining 20% of the predicted collection set, which would consist of only old regions, then forms the optional part.

After G1 finishes collecting the mandatory part, G1 starts collecting the optional part at a much more granular level, if there is time left. The granularity of collection of this optional part depends on the amount of time left, at most down to one region at a time. After completing collection of any part of the optional collection set, G1 can decide to stop the collection depending on the remaining time.

As the predictions get more accurate again, the optional part of a collection are made smaller and smaller, until the mandatory part once again comprises all of the collection set (i.e., G1 completely relies on its heuristics). If the predictions becomes inaccurate again, then the next collections will consist of both a mandatory and optional part again.

JEP 346: Promptly Return Unused Committed Memory from G1

JEP 346 enhance the G1 garbage collector to automatically return Java heap memory to the operating system when idle.

Currently G1 only returns memory from the Java heap at either a full GC or during a concurrent cycle. Since G1 tries hard to completely avoid full GCs, and only triggers a concurrent cycle based on Java heap occupancy and allocation activity, it will not return Java heap memory in many cases unless forced to do so externally.

Download JDK 12

Java SE Development Kit 12 is available for download since March 19, 2019 in Oracle's download page.