This is the third in a series of articles looking at some of the JDK Enhancement Proposals (JEPS) hoping to make their way into Java 9. Last week we looked at the HTTP/2 Client.

This week we look at some of the JVM changes you can expect in Java 9: JEP 165, JEP 158 and JEP 271.

Compiler Control

JEP 165: Compiler Control proposes an improved way to control the JVM compilers.

The two existing compilers are C1 and C2. The C1 compiler is a fast, lightly optimising bytecode compiler. This is predominantly used for applications that need a quick start-up, and is typically used for client applications. The C2 compiler (‘opto’) is a highly optimising bytecode compiler. This is predominantly used for long-running server applications and provides more advanced optimisation. Modern Java applications can take advantage of both using tiered compilation, which starts an application using the C1 compiler and then uses the C2 compiler for more advanced optimisations. See this primer on JIT compilation in Java HotSpot VM for more information.

The Compiler control proposal aims to provide:

  • ‘Fine-grained and method-context dependent control of the JVM compilers (C1 and C2)’, and
  • ‘The ability to change the JVM compiler control options in run time’

with no performance degradation. This will be achieved by gathering all of the JVM compiler options into one set – a ‘compiler directive’. A method matcher is used to match the options with methods, and directives can be added or removed at runtime. This is a huge advantage for anyone wishing to run tests on the JVM code without having to stop and start the JVM.


Due to the number of compiler options, only a subset will be available initially. The options will be in the compiler directive. The directives will be in the form of JSON. For example:

[    // Start of array of directives
    {   // Start of directive block
        // Exactly one match with one or several patterns
        // The array is not required with a single pattern
        match: ["java*.*", "oracle*.*"],   
        // A directives block that only applies to a single compiler
        c1: {   
             // A bool option. Extra trailing comma should not cause a parse error 
        // Another compiler block
        c2: {
             // force inline patterns prepended with +, prevent with -
             inline: ["+vm*.*","-*.*" ] 
        // Options outside compiler block apply to all compilers
        BreakAtExecute: true   // enable break in compiled code 
        BreakAtCompile: true   // enable break in compiler
    {  // Start of another directives block
        // Match any method whose class ends with 'Concurrent'
        match: ["*Concurrent.*"],    
        c2: {
             // disable compilation
        // As the c1 directive is unspecified, the default options are used.

Example from JEP 165

The directives parser parses the directives file. It validates the options and prints warnings if there are any platform dependent options on unsupported platforms.

Directives files can be added on the command line, using --XX:CompilerDirectivesFile=<file>.

JVM Logging

There are few things worse than trying to solve mysterious memory issues with insufficient logging.

Unified JVM Logging

This JEP aims to speed up analysis when looking at JVM issues such as memory, crashes, and performance issues. It does not aim to add logging calls from all JVM components, or introduce a logging format, but to provide infrastructure to do the logging.

This will bring JVM logging in line with other logging frameworks like Log4j. A few of the ways it will do this by:

Introducing common command-line options for all logging

Using -Xlog, multiple arguments can be applied and arguments for the same output will override each other in the order they are supplied. An example argument is -Xlog:disable which turns off all logging and clears all configuration of the logging framework, including warnings and errors.

Categorising log messages using tags

Each tag is identified by its name (e.g. ‘compiler’, ‘gc’), and the set can be changed in the source code. Log messages should be associated with a tag-set to classify the information, which contains one or more tags.

Performing logging at different levels

Like Log4j, logging can be performed at different levels e.g. warning, info, debug. This makes it easier to change the amount of information you want to receive to the log file, and allows you to select what messages are logged depending on the level.

Redirect and decorate logging

Logging can be decorated with information about the message with options such as

  • time – in ISO-8601 format
  • uptime – time since the start of the JVM in seconds and milliseconds
  • pid – process ID
  • level – the level of the message (e.g. warning, debug, error)
  • tags – the tag set, e.g. ‘compiler’, ‘gc’

The output can be directed to stdout, stderr or a text file.

Unified GC Logging

Following on from the Unified JVM Logging, no garbage collection log messages will stay the same. Unified GC Logging uses the new logging framework introduced with the ‘gc’ tag. So for example, --XX:+PrintGC, which would print one line per garbage collection, becomes something like -Xlog:gc. This only logs on the ‘gc’ tag at info level, so the method log_info(gc)("logging") should only print one message per garbage collection in order to maintain a faithful mapping.

There will not be strict mappings. The unified logging framework adds the GC ID to the log messages using prefix support from the Unified JVM Logging proposal. The prefixes are defined per tag-set. Thus as the GC ID is only relevant for logging that happens during a garbage collection, any logging in between garbage collections should use a different tag-set than ‘gc’.

The changes to logging do not ensure that current garbage collection log parsers work without any changes to the new garbage collection logs. As there won’t be strict mappings, not all log entries will have an alternative in the new format.

What this means for you

Due to the change in log message formats, logging options may have to change as well as some JVM options such as --XX:+PrintGC. As with other logging frameworks such as Log4j, if logging levels aren’t carefully tuned performance could be impacted (for example using the level debug in a production environment.

This brings the inbuilt Java logging options in line with other logging frameworks. Some configuration will have to be done to map to the new framework, but the ability to configure the level of the logging and the introduction of common command-line options will certainly be useful.

Next up: Javadoc and HTML5

Java 9 series: the JVM

| Java Language| 1,672 views | 0 Comments
About The Author
- Katharine is a Java developer by trade, turned Community & Content Manager for Voxxed. Helping developers learn and share knowledge. Contact me at with any news, articles or tutorials.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>