Simplified Java coding. Less garbage. Faster programs. Those are among the key features in the newly released Java 10, which arrived in developers’ hands only six months after the debut of Java 9 in September.
This pace is a significant change from Java’s previous cycle of one large release every two to three years. With its faster release cadence, Java is poised to provide developers with innovations twice every year, making the language and platform more attractive and competitive. Instead of waiting for a huge omnibus release, the Java community can choose to include new features as soon as those features are ready, in the next six-month Java release train. This gives developers access to the latest APIs, functions, language additions, and JVM updates much faster than ever before.
Java 10 is the first release on the new six-month schedule, and it builds incrementally on the significant new functionality that appeared in Java 9, which had a multiyear gestation period.
Java 10 delivers 12 Java Enhancement Proposals (JEPs). Here’s the complete list, followed by a deeper look at three of the most significant JEPs:
- Local-Variable Type Inference
- Consolidate the JDK Forest into a Single Repository
- Garbage-Collector Interface
- Parallel Full GC for G1
- Application Class-Data Sharing
- Thread-Local Handshakes
- Remove the Native-Header Generation Tool (javah)
- Additional Unicode Language-Tag Extensions
- Heap Allocation on Alternative Memory Devices
- Experimental Java-Based JIT Compiler
- Root Certificates
- Time-Based Release Versioning
Let’s look at three of the most significant JEPs: Local-Variable Type Inference, Parallel Full GC for G1, and the Experimental Java-Based JIT Compiler.
Local Variable-Type Inference
Local variable-type inference reduces some of the overhead required to use variables whose scope only includes a single Java module. As a design principle, Java requires all variables to be explicitly typed—that is, the programmer must state, very clearly, the type of data that will be contained by a variable. This ensures that every module or class that uses the variable interprets its contents the same way. This principle, called “type safety,” minimizes runtime errors.
However, there can be many more variables used strictly internally within a single module, such as loop iterators, or variables containing intermediate values within a complex calculation. Explicitly typing such variables is not only time-consuming but could potentially lead to human error by the programmer. With local variable-type Inference, the programmer simply initiates the variable using special syntax, and the Java compiler then infers the type from context. Less coding plus fewer errors equal happy developers.
Parallel Full GC for G1
The GC is the Java garbage collector, which reclaims objects that are no longer being used but are still consuming memory. The GC must be run periodically to ensure long-running programs, such as those on enterprise servers or in the cloud, don’t run out of memory. The garbage collector is an essential part of any Java Virtual Machine, and it’s essential that the GC runs as quickly as possible and itself consumes as few resources as possible.
Most of the time, the GC runs at the same time as the JVM’s application programs. This minimizes impact on running software but doesn’t allow for the most efficient garbage collection. Sometimes it’s necessary to temporarily freeze the execution of running programs and give the garbage collection exclusive access to the JVM’s processors and memory. This is called a “Full GC,” and in order to minimize disruption to users of the software running in the JVM, the Full GC must be superfast and superefficient.
What’s new in Java 10 is that the Full GC process has been optimized to run in parallel threads, using all the processors available to the JVM in a multi-processor environment. The benefit: Minimal impact on applications—and on users.
Experimental Java-Based JIT Compiler
Here’s an example of a feature included in Java 10 that’s not entirely ready for prime time, and that’s why it’s called experimental. Let’s take a step back. Most of the time, a programmer’s Java programs are executed in the JVM as bytecode. However, sometimes the JVM uses a compiler to translate the bytecode into machine code to improve performance.
The program that translates the Java code into machine code is called a just-in-time (JIT) compiler. JIT compilers are complicated, and must be customized for each platform to generate machine code compatible with that platform's particular microprocessors and operating systems.
The good news: Java has long included JIT compilers, and developers rely upon them to write very efficient applications. The bad news: Java’s JIT compilers are written in C++, and those compilers are old and can be hard to maintain. Also sometimes, especially at system startup, the “just-in-time” compilation can be slower than desired.
That’s where Experimental Java-based JIT Compiler comes in. It’s written in Java, which makes it easier for the Java community to maintain because it's not written in a different language (C++). And it uses a function called Ahead-of-Time (AOT) compilation to compile Java classes and methods in advance, to shorten the startup time.
Including the experimental Java-based JIT compiler in Java 10 gives developers the opportunity to kick the tires on the compiler and its AOT functionality, use it when appropriate, and provide feedback to the Java community, years earlier than would have been possible with the old two- to three-year Java release cadence.
As the first of the semiannual Java releases, Java 10 includes a dozen features that build upon the major work done in Java 9. Not only do Java developers have the latest innovations, they’ve received such innovations faster than ever before and can use them in applications being written today.
Alan Zeichick is director of strategic communications for Oracle, where he provides insights and analysis on cloud computing and other advanced technologies. Follow him at @zeichick.