What is new in Java 9 ? Part 2: Runtime and Internal Changes

December 18, 2018

THIS POST IS NOT COMPLETE. IT STAYED SO LONG AS DRAFT IN MY FOLDER, I DECIDED TO PUBLISH IT ANYWAY.

Introduction

This is a follow up post to What is new in Java 9 ? Part 1: Developer Perspective. Below is a list of changes that are not directly visible to developers.

All the JEPs listed here are taken from: http://openjdk.java.net/projects/jdk9/.

JEP 143: Improve Contended Locking

The performance of locks used by multiple threads’ access to a synchronized block is improved. Very basically it means multi-thread performance is increased.

More information here: https://ionutbalosin.com/2018/06/contended-locks-explained-a-performance-approach/

JEP 158: Unified JVM Logging

As the name suggests, this unifies the logging from different components of JVM into a common framework with -Xlog option.

Use -Xlog:help to learn about all possible options.

The usage is:

-Xlog Usage: -Xlog[:[what][:[output][:[decorators][:output-options]]]]
	 where 'what' is a combination of tags and levels of the form tag1[+tag2...][*][=level][,...]
	 Unless wildcard (*) is specified, only log messages tagged with exactly the tags specified will be matched.

There are many available tags such as: class, init, gc.

The log levels are : off, trace, debug, info, warning, error.

The output can be stdout, stderr or a file=.

It is also possible to add decorators to the log lines such as: tid, timemillis, timenanos, level.

Use -Xlog:all=trace:stdout to print everything (and it is a lot) to stdout. Lets try this with the JEP102 example above:

$ java -Xlog:all=trace:file=xlog.out:tags,level,tid,timemillis JEP102
$ wc -l xlog.out
17139 xlog.out
$ cat xlog.out | grep class,init | grep JEP102
[1543912650088ms][1314][info ][class,init                  ] Start class verification for: JEP102
[1543912650088ms][1314][info ][class,init                  ] End class verification for: JEP102
[1543912650089ms][1314][info ][class,init                  ] 404 Initializing 'JEP102' (0x00000007c0060028)
[1543912650125ms][1314][info ][class,init                  ] Start class verification for: JEP102$$Lambda$3/1983747920
[1543912650125ms][1314][info ][class,init                  ] End class verification for: JEP102$$Lambda$3/1983747920
[1543912650125ms][1314][info ][class,init                  ] 527 Initializing 'JEP102$$Lambda$3'(no method) (0x00000007c0075c28)

As you see, a log can have multiple tags, and can be specified with a + in what string, like class+init.

JEP 165: Compiler Control

This introduces a way to control the JVM compilers (C1 and C2) at method level, and also at run-time.

A configuration containing directives is given to JVM. A directive contains a matcher to select methods it applies and options for compilation.

As an example, lets disable all compilation with the following directive:

[
  {
    match: "*.*",
    c1: {
      Exclude: true
    },
    c2: {
      Exclude: true
    }
  }
]

Then, we can provide this to JVM (the class JEP165 contains just an infinite loop):

$ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -XX:CompilerDirectivesFile=compiler.directives JEP165

This is going to output compilation logs like this:

...
#### Excluding compile: java.lang.String::indexOf
made not compilable on levels 0 1 2 3  java.lang.String::indexOf (7 bytes)   excluded by CompileCommand
...

It is also possible to query and modify compiler directives run-time using jcmd:

$ jcmd `jps | grep JEP165 | cut -f1 -d' '` Compiler.directives_print

will display the compiler directives we supplied above.

JEP 197: Segmented Code Cache

When Java bytecodes are compiled, the compiled code is kept in the code cache (or code heap). Before Java 9, there was a single memory area for any compiled code. With Java 9, a segmented code cache is also supported with three separate areas (heaps):

  • Non Profiled, i.e. methods compiled at level 1 or 4 and native methods
  • Profiled, i.e. methods compiled at level 2 or 3
  • Non Method, i.e. JVM internal methods like buffers, adapters and runtime stubs

The related flags can be seen below:

$ java -XX:+PrintFlagsFinal | grep -e CodeCache -e CodeHeap
    uintx CodeCacheExpansionSize              = 65536              {pd product} {default}
    uintx InitialCodeCacheSize                = 2555904            {pd product} {default}
    uintx NonNMethodCodeHeapSize              = 5830092            {pd product} {ergonomic}
    uintx NonProfiledCodeHeapSize             = 122914074          {pd product} {ergonomic}
     bool PrintCodeCache                      = false              {product} {default}
     bool PrintCodeCacheOnCompilation         = false              {product} {default}
    uintx ProfiledCodeHeapSize                = 122914074          {pd product} {ergonomic}
    uintx ReservedCodeCacheSize               = 251658240          {pd product} {ergonomic}
     bool SegmentedCodeCache                  = true               {product} {ergonomic}
     bool UseCodeCacheFlushing                = true               {product} {default}

Segmented Code Cache is enabled SegmentedCodeCache=true.

JEP 199: Smart Java Compilation, Phase Two

sjavac (Smart Java Compiler) is used more and more reliably and supported by more/all build configurations in JDK builds. However, sjavac is not shipped in the JDK product yet.

JEP 201: Modular Source Code

JDK source code is reorganized into modules, following this form:

src/$MODULE/{share,$OS}/classes/$PACKAGE/*.java
                        native/include/*.{h,hpp}
                               $LIBRARY/*.{c,cpp}
                        conf/*
                        legal/*

For example the directory tree of src/java.base is below. I have folded some of the subfolders and marked them with … .

.
├── aix
│   ...
├── linux
│   ├── classes
│   │   └── sun
│   │       └── nio
│   │           ├── ch
│   │           └── fs
│   └── native
│       ├── libjava
│       ├── libnet
│       └── libnio
│           ├── ch
│           └── fs
├── macosx
│   ...
├── share
│   ├── classes
│   │   ├── META-INF
│   │   │   └── services
│   │   ├── com
│   │   │   └── sun
│   │   │       ├── crypto
│   │   │       │   └── provider
│   │   │       ├── java
│   │   │       │   └── util
│   │   │       │       └── jar
│   │   │       │           └── pack
│   │   │       ├── ...
│   │   ├── java
│   │   │   ├── io
│   │   │   ├── lang
│   │   │   │   ...
│   │   │   ├── math
│   │   │   ├── net
│   │   │   │   ├── doc-files
│   │   │   │   └── spi
│   │   │   ├── nio
│   │   │   │   ...
│   │   │   ├── security
│   │   │   │   ├── acl
│   │   │   │   ├── cert
│   │   │   │   ├── interfaces
│   │   │   │   └── spec
│   │   │   ├── text
│   │   │   │   └── spi
│   │   │   ├── time
│   │   │   │   ├── chrono
│   │   │   │   ├── format
│   │   │   │   ├── temporal
│   │   │   │   └── zone
│   │   │   └── util
│   │   │       ...
│   │   ├── javax
│   │   │   ├── crypto
│   │   │   │   ├── interfaces
│   │   │   │   └── spec
│   │   │   ├── net
│   │   │   │   └── ssl
│   │   │   └── security
│   │   │       ├── auth
│   │   │       │   ├── callback
│   │   │       │   ├── login
│   │   │       │   ├── spi
│   │   │       │   └── x500
│   │   │       └── cert
│   │   ├── jdk
│   │   │   └── internal
│   │   │       ...
│   │   └── sun
│   │       ├── invoke
│   │       │   ├── empty
│   │       │   └── util
│   │       ├── launcher
│   │       │   └── resources
│   │       ├── net
│   │       │   ...
│   │       ├── nio
│   │       │   ├── ch
│   │       │   ├── cs
│   │       │   └── fs
│   │       ├── reflect
│   │       │   ...
│   │       ├── security
│   │       │   ...
│   │       ├── text
│   │       │   ├── bidi
│   │       │   ├── normalizer
│   │       │   ├── resources
│   │       │   │   └── cldr
│   │       │   └── spi
│   │       └── util
│   │           ...
│   ├── conf
│   │   └── security
│   │       └── policy
│   │           ├── limited
│   │           └── unlimited
│   ├── legal
│   ├── lib
│   │   └── security
│   └── native
│       ├── include
│       ├── launcher
│       ├── libfdlibm
│       ├── libjava
│       ├── libjimage
│       ├── libjli
│       ├── libnet
│       ├── libnio
│       │   └── ch
│       ├── libverify
│       └── libzip
│           └── zlib
│               └── patches
├── solaris
│   ...
├── unix
│   ...
└── windows
    ...

There are 380 directories.

JEP 212: Resolve Lint and Doclint Warnings

Lint and Doclint warnings in all or fundamental packages are fixed in the JDK build.

JEP 214: Remove GC Combinations Deprecated in JDK 8

Garbage Collector combinations, deprecated in JDK 8 (with JEP 173) and with issue JDK-8027876, are removed. These are:

  • DefNew + CMS
  • ParNew + SerialOld
  • Incremental CMS (iCMS), thus ParNew + iCMS and DefNew + iCMS
  • CMS foreground

So the following flag combinations will stop working (taken from the JEP):

  • DefNew + CMS : -XX:-UseParNewGC -XX:+UseConcMarkSweepGC
  • ParNew + SerialOld : -XX:+UseParNewGC
  • ParNew + iCMS : -Xincgc
  • ParNew + iCMS : -XX:+CMSIncrementalMode -XX:+UseConcMarkSweepGC
  • DefNew + iCMS : -XX:+CMSIncrementalMode -XX:+UseConcMarkSweepGC -XX:-UseParNewGC
  • CMS foreground : -XX:+UseCMSCompactAtFullCollection
  • CMS foreground : -XX:+CMSFullGCsBeforeCompaction
  • CMS foreground : -XX:+UseCMSCollectionPassing

JEP 215: Tiered Attribution for javac

A new method type-checking strategy, tiered attribution (TA), is introduced to resolve the performance problems with overloaded methods and/or nested method calls.

JEP 217: Annotations Pipeline 2.0

With the introduction of new annotation features in Java 8 (with JEP 120 and JEP 104) and new syntactic positions for annotations with Lambda Expressions (in JEP 126), the existing annotation processing pipeline inside javac became “brittle” and “hard-to-maintain”. This is resolved by refactoring the pipeline.

JEP 220: Modular Run-Time Images

TODO:

JEP 221: Simplified Doclet API

“old Doclet API” (com.sun.javadoc) is frozen and the “new Doclet API” (jdk.javadoc.doclet) is introduced. javadoc supports both for the moment.

JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)

Interactive REPL tool and API for Java is introduced. It is called JShell, provided by the new tool jshell and the API (jdk.jshell).

JEP 223: New Version-String Scheme

JDK adapted an easier to understand versioning model.

Version Number VNUM is always MAJOR.MINOR.SECURITY. Note that SECURITY is not reset to zero when MINOR is incremented. Also, when MAJOR is incremented, all other elements are removed.

Version String VSTR is Version Number VNUM, an optional PRE (pre-release identifier), the build number BUILD and an optional build information OPT. Note that BUILD is reset to one when any part of VNUM is changed.

So the new version history would be like:

  • an early access release

    9-ea+19: VNUM.MAJOR=9, PRE=ea(early access), BUILD=19

  • a release, build number is not reset

    9+100: VNUM.MAJOR=9, BUILD=100

  • a security update, build number is reset

    9.0.1+20: VNUM.MAJOR=9, VNUM.SECURITY=1, BUILD=20

  • another security update, build number is reset

    9.0.2+12: VNUM.MAJOR=9, VNUM.SECURITY=2, BUILD=12

  • a minor update with existing security version (no new security enhancement), build number is reset

    9.1.2+62: VNUM.MAJOR=9, VNUM.MINOR=2, VNUM.SECURITY=2, BUILD=62

  • another security update, build number is reset

    9.1.3+15: VNUM.MAJOR=9, VNUM.MINOR=2, VNUM.SECURITY=3, BUILD=15

Lets see the version of Java 9 I am using:

./java -version
openjdk version "9"
OpenJDK Runtime Environment (build 9+181)
OpenJDK 64-Bit Server VM (build 9+181, mixed mode)

JEP 228: Add More Diagnostic Commands

Many more diagnostic commands are introduced with Java 9.

$ jcmd JEP165 help
2703:
The following commands are available:
VM.log
VM.native_memory
ManagementAgent.status
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
Compiler.directives_clear
Compiler.directives_remove
Compiler.directives_add
Compiler.directives_print
VM.print_touched_methods
Compiler.codecache
Compiler.codelist
Compiler.queue
VM.classloader_stats
Thread.print
JVMTI.data_dump
JVMTI.agent_load
VM.stringtable
VM.symboltable
VM.class_hierarchy
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.info
VM.uptime
VM.dynlibs
VM.set_flag
VM.flags
VM.system_properties
VM.command_line
VM.version
help

JEP 232: Improve Secure Application Performance

Some optimizations and enhancements are made for applications running with a security manager installed.

JEP 233: Generate Run-Time Compiler Tests Automatically

jittester (internal) tool that generates correct Java source code or byte code and verifies the output of runs both in interpreted and compiled modes is introduced.

JEP 235: Test Class-File Attributes Generated by javac

Test coverage for Class-file attributes are improved.

JEP 237: Linux/AArch64 Port

Linux/AAarch64 (new processor architecture from ARM) port is integrated into JDK.

JEP 240: Remove the JVM TI hprof Agent

hprof agent library (libhprof.so) is removed. The alternatives of this functionality is available as heap dumps, allocation profiler and CPU profiler.

JEP 241: Remove the jhat Tool

jhat heap analyzer is removed.

JEP 243: Java-Level JVM Compiler Interface

A Java based JVM compiler interface (JVMCI) is developed to enable a compiler written in Java to be used as a JVM compiler. A famous such compiler is Graal.

JEP 245: Validate JVM Command-Line Flag Arguments

All JVM flags are now range and constraint checked before launching the program and display a warning and informative message if there is an error. For example:

$ java -XX:CompilationPolicyChoice=4

intx CompilationPolicyChoice=4 is outside the allowed range [ 0 ... 3 ]
Improperly specified VM option 'CompilationPolicyChoice=4'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

JEP 246: Leverage CPU Instructions for GHASH and RSA

The performance of GHASH (used in GCM) and RSA operations are improved by using new CPU instructions, pclmulqdq and Bit Manipulation Instruction Set 2 on Intel x64. 

From the hotspot source code:

// GHASH/GCM intrinsics
if (UseCLMUL && (UseSSE > 2)) {
  if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
    UseGHASHIntrinsics = true;
  }
} else if (UseGHASHIntrinsics) {
  if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics))
    warning("GHASH intrinsic requires CLMUL and SSE2 instructions on this CPU");
  FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
}

JEP 248: Make G1 the Default Garbage Collector

Low-Pause GC collector G1 is now default on server configurations.

JEP 250: Store Interned Strings in CDS Archives

Memory consumption is reduced by storing interned strings in class-data sharing (CDS) archives.

JEP 252: Use CLDR Locale Data by Default

The default locale data is changed to be CLDR (provided by Unicode Consortium). JRE (or COMPAT designation) is now the second preference in the locale provider.

JEP 255: Merge Selected Xerces 2.11.0 Updates into JAXP

JDKs copy of Xerces is updated to 2.11.0. This does not affect the JAXP public API.

JEP 257: Update JavaFX/Media to Newer Version of GStreamer

The GStreamer included in JavaFX/Media is updated to newer version.

JEP 258: HarfBuzz Font-Layout Engine

Since the ICU OpenType is no longer actively developed, JDK has moved to use HarfBuzz engine. This is an internal change, however minor visual differences can be observed in text rendering.

JEP 261: Module System

Implements the Java Platform Module System (JSR 376). This is a very big change and it touches JEP 200, 201, 220, 260 and 282.

“link time” phase is introduced optionally between compile time (javac) and run time (java), that can be run by the link tool (jlink, JEP 282). Linking assembles the modules into a custom run-time image.

JEP 263: HiDPI Graphics on Windows and Linux

Support for HiDPI graphics is implemented, so icons, images, text and GUI components are scaled according to the DPI of the display. JDK already supports HiDPI displays on Mac OS X.

JEP 264: Platform Logging API and Service

A minimal logging API introduced for platform (Java internal) classes to log messages and make it possible to route these messages to a logging framework of choice.

JEP 265: Marlin Graphics Renderer

Java 2D starts using Marlin Renderer by default instead of Pisces.

JEP 270: Reserved Stack Areas for Critical Sections

When a method tries to modify the stack beyond the point allowed, JVM raises a StackOverflowError. However, this may cause inconsistencies especially if the code inside the critical section causes the stack overflow.

This JEP introduces an annotation, jdk.internal.vm.annotation.ReservedStackAccess, and this causes to delay the StackOverflowError in the critical sections in this method. If the method is not annotated as such, StackOverflowError is thrown immediately which is the current (default) behavior. This annotation can only be used by (or taken into account when used by) priviliged code, the code loaded by the bootstrap class loader.

JEP 271: Unified GC Logging

Logging used by GCs are reimplemented to use Unified JVM Logging (JEP 158) with -Xlog:gc.

JEP 275: Modular Java Application Packaging

javapackager tool is aligned with modular Java.

JEP 276: Dynamic Linking of Language-Defined Object Models

TODO:

JEP 278: Additional Tests for Humongous Objects in G1

Humongous Objects are objects bigger than a half of a memory region, and G1 (Garbage First) garbage collector treats them differently than other objects. New tests, and required additional code for these tests, are implemented with this JEP.

JEP 279: Improve Test-Failure Troubleshooting

More diagnostic information is collected when an internal JDK test fails.

JEP 281: HotSpot C++ Unit-Test Framework

Google Test framework (GTest) is integrated to HotSpot project to make it easier to write unit tests.

JEP 283: Enable GTK 3 on Linux

Java graphics system is updated to support GTK 3 on Linux.

JEP 284: New HotSpot Build System

The build system for HotSpot component (JVM) in JDK source code is rewritten to use the already present functionality present in the build-infra framework.

JEP 291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector

Concurrent Mark Sweep (CMS) garbage collector is deprecated and will be removed in the future.

JEP 294: Linux/s390x Port

s390x (also known as “System z” or “z/Architecture”) port is integrated into JDK.

JEP 297: Unified arm32/arm64 Port

arm32/arm64 (of aarch32) port contributed by Oracle is integrated into JDK.

JEP 298: Remove Demos and Samples

Demos and samples in jdk/src/demo and jdk/src/sample are removed.

JEP 299: Reorganize Documentation

The documents both at source code level and the generated ones are reorganized.