Raw String Literals Removed From Java 12 as Feature Set Frozen


The next version of Java SE, JDK 12, has reached the first ramp-down point where the feature set is frozen. Amongst other things JDK 12 provides a preview of an enhanced switch statement, adds a number of improvements to the G1 garbage collector, and introduces a new experimental garbage collector called Shenandoah.

But one major proposal for JDK 12, raw string literals, has been removed. According to the JEP  "A raw string literal can span multiple lines of source code and does not interpret escape sequences, such as \n, or Unicode escapes of the form \uXXXX". So for example instead of writing

 String html = "<html>\n" + " <body>\n" + " <p>Hello World.</p>\n" + " </body>\n" + “</html>\n";

You could write

 String html = `<html> <body> <p>Hello World.</p> </body> </html> `;

"...we think letting it preview in its current state would be to the detriment of the language" wrote Brian Goetz in an email explaining the decision:

We're of course disappointed that this means it will take slightly longer for this feature to make it into the language, but we think that's the best choice.

While we can expect that for any language feature, there will be a nontrivial volume of "I would have preferred it differently" feedback, in reviewing the feedback we have received, I am no longer convinced that we've yet got to the right set of tradeoffs between complexity and expressiveness, or that we've explored enough of the design space to be confident that the current design is the best we can do.  By withdrawing, we can continue to refine the design, explore more options, and aim for a preview that actually meets the requirements of the Preview Feature process (JEP 12).

In terms of new language features that have been added, JDK 12 adds the aforementioned JEP 325: Switch Expressions as a preview feature. There are two main changes to switch in Java with this JEP. The first is a new form of switch label, written "case L ->" to signify that only the code to the right of the label is to be executed if the label is matched:

 switch (day) { case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); case TUESDAY -> System.out.println(7); case THURSDAY, SATURDAY -> System.out.println(8); case WEDNESDAY -> System.out.println(9); }

The second is that switch can be an expression, so it can have a value, or it can return a value:

 T result = switch (arg) { case L1 -> e1; case L2 -> e2; default -> e3; }; 

JDK 12 also makes a couple of significant enhancements to the G1 garbage collector. One of the goals of G1 is to meet a user-supplied pause time target for its collection pauses, however in certain circumstances the collector can fail to meet this goal. This happens because G1 uses a set of heuristics to select the amount of work to be done during a collection - the collection set. However at present G1 must collect all live objects in all regions of the collection set without stopping. Thus if the collector's heuristics choose a too-large collection set, which can happen if the application behaviour changes and the heuristics work on "stale" data, then the collector can exceed the pause target.

In order to meet the user-supplied pause time target, JEP 344 makes the G1 garbage collector abort the garbage collection process, by splitting the set of to-be-garbage-collected regions (mixed collection set) into mandatory and optional parts. It can abort the collection of the optional part if the pause time target will not be reached otherwise.

Another issue that G1 has is that it does not always return committed Java heap memory to the operating system in a timely manner, since G1 only returns memory from the Java heap at either a full GC or during a concurrent cycle. As JEP 346 points out

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.

This behavior is particularly disadvantageous in container environments where resources are paid by use.

The stated goal of this JEP is to enhance the G1 garbage collector to automatically return Java heap memory to the operating system when idle.

As well as enhancements to G1, JDK 12 adds a new experimental garbage collector called Shenandoah which is intended to reduce GC pause times by doing evacuation work concurrently with the running Java threads.

Shenandoah has been developed by Red Hat. It is a mark/copy collector and is similar in many respects to G1. The principle difference is that the collector makes use of Brooks forwarding pointers during the evacuation phase. The idea is that each object on the heap has one additional reference field. This field either points to the object itself or, as soon as the object gets copied to a new location, to its new location. This will enable it to evacuate objects concurrently with mutator threads.

Pause times with Shenandoah are independent of heap size, but the collector comes with a performance penalty so it is primarily more useful for applications with larger heaps. The algorithm is described in depth in this PPPJ2016 paper.

Other features in JDK 12 will include:

  • JEP 334: Proposes an API to model nominal descriptions of key class-file and run-time artefacts, in particular constants that are loadable from the constant pool. The draft of this API is available here.
  • JEP 230: A suite of microbenchmarks, to easily test the performance of JDK, based on Java Microbenchmark Harness (JMH).
  • JEP 340: There are two different set of sources, thus ports, targeting ARM 64-bit in the JDK. One is contributed by Oracle, arm64, and the other is aarch64. This JEP will remove all of the sources related to the arm64 port while retaining the 32-bit ARM port and the 64-bit aarch64 port.
  • JEP 341: Class Data-Sharing (CDS) is a feature to reduce startup time and benefit from memory sharing - the JEP mentions a 32% startup time reduction running HelloWorld. However users who want to take advantage of CDS, even with just the default class list provided in the JDK, must run java -Xshare:dump as an extra step. With this JEP, the CDS archive will be generated by default.

The release candidate for JDK 12 is expected in early February, with the GA release in mid March.