Saturday, May 7, 2016

HotSpot Incremental Java Garbage Collector

In my recent blog post Determining the Active HotSpot Garbage Collector, I described different approaches that can be used to determine the garbage collector that is being used by HotSpot JVM (Java process) when it is not obvious from the command-line arguments (flags) passed to the Java launcher. For significant Java applications, I prefer to explicitly specify the appropriate garbage collector flag with the Java launcher to leave out any doubt as to which collector is being used: -XX:+UseParallelGC (or -XX:+UseParallelOldGC) for the parallel/throughput collector, -XX:+UseConcMarkSweepGC for the Concurrent Mark Sweep (CMS) collector, -XX:+UseG1GC for Garbage-First Garbage Collector, and -XX:+UseSerialGC for Serial Garbage Collector.

When none of these are garbage collector JVM flags are explicitly specified, the virtual machine selects a garbage collector and which collector has been selected by the VM can be identified using JDK command-line tool jcmd or its related JMX MBean implementation DiagnosticCommandMBean (often via JConsole or VisualVM). In some cases, a particular garbage collector is specified because of the existence of a particular HotSpot JVM flag not in my previous list. In this post, I look briefly at one of these: -Xincgc.

The Oracle-provided JDK Tools and Utilities documentation for the Java launcher java briefly describes -Xincgc. The documentation for Java SE 6's java executable and for Java SE 7's java executable describe -Xincgc: "Enable the incremental garbage collector. The incremental garbage collector, which is off by default, will reduce the occasional long garbage-collection pauses during program execution. The incremental garbage collector will at times execute concurrently with the program and during such times will reduce the processor capacity available to the program."

Java SE 8's version of the java documentation states of -Xincgc: "Enables incremental garbage collection. This option was deprecated in JDK 8 with no replacement." The incremental collector is deprecated as of Java 8, which is confirmed in the "Deprecated APIs" section of the Compatibility Guide for JDK 8: "The -Xincgc option is deprecated." More details on why this and other garbage collection combinations have been deprecated in JDK 8 can be found in JEP 173 ("Retire Some Rarely-Used GC Combinations") and in JEP 214 ("Remove GC Combinations Deprecated in JDK 8").

It appears that -Xincgc will not be available after JDK 8. For versions of the JVM that support -Xincgc, a question might be what it means in terms of garbage collector to run the incremental garbage collector. The previously referenced Compatibility Guide for JDK 8 states that "Incremental CMS" is one of the now deprecated "garbage collector combinations." It has also been stated that "-Xincgc simply translates" in Java 6 to "-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode." The next two screenshots demonstrate this is the case in Java 8 for a small, simple Java application. The first snapshot depicts the running of the same executable JAR (-jar) with and without -Xincgc specified. The second snapshot depicts the different VM-selected command-line flags for this same application that are a result of having or not having -Xincgc specified.

These screenshots demonstrate that the Java 8 VM used against this simple executable JAR application chooses the parallel/throughput collector (-XX:+UseParallelGC ) when -Xincgc is not specified and chooses the CMS collector (-XX:+UseConcMarkSweepGC) with additional flag -XX:+CMSIncrementalMode when -Xincgc is explicitly specified. It's also worth pointing out that when running the Java 8 HotSpot Java launcher with -Xincgc, a deprecation warning message is presented (I've added the emphasis): "Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future version."

I decided it was worth posting on a deprecated JVM flag related to garbage collection because there are some high-level observations that can be made from this discussion:

  • Besides the HotSpot VM flags that directly specify a particular garbage collector, other flags can imply a garbage collector.
  • The jcmd tool is useful for identifying which garbage collector is in use not only in cases where no JVM flags are provided, but also for cases where a flag is used that implies a particular collector (such as -Xincgc implying CMS collector in this example).
  • The incremental CMS Collector is going away. Anyone considering upgrading to Java 9 might find it prudent to inspect the VM flags their applications use to identify cases where the incremental CMS collector (-Xincgc) is currently being used. If running on Java 8, there should already be a deprecation warning as demonstrated in this post.
  • This is a reminder that while Java and the JVM remain largely backwards compatible language and platform, there are features and capaibilities that are removed from time to time (typically rarely used things or things that are significantly flawed).

No comments: