JDK 9 Migration : 5 point checklist for Garbage Collection

Thinking of migrating your applications to JDK 9? Although there are many changes to be aware of for a successful JDK 9 migration, I’ll focus on summing up the Garbage Collection changes you’ll need to have on your radar in order to avoid some possible surprises.

To be fair, some of these changes have already been marked as deprecated in JDK 8 so these shouldn’t be totally surprising. However, there are many that have abused Java’s commitment to backwards compatibility even when future deprecation has clearly been documented – not talking about you 😉

A friend of mine always use to say (and it stuck with me) …

Pay now or pay later with interest!

Seems fitting in this context.

Say hello to a new word in the Java vocabulary … “removal“! Yes, that’s right, the flinching game is over.

The Elephant in the Room – G1

By far, the biggest change to Garbage Collection in JDK 9 is the new default Garbage Collector named “G1” for 32/64-bit server configurations.

The previous default was the Parallel GC and the decision was made to favor a low-pause collector (G1) instead of maximizing throughput. If this assumption is correct, it should provide a better overall experience to the majority of applications.

However, if that assumption is wrong for your application because it’s resource usage overhead needs to be minimized, then you’ll have to explicitly define another collector. This is due to the G1 collector being more CPU hungry/intensive than other Garbage Collectors.

What Should I do? …..

  • If your 100% sure your current GC is right for your application then just explicitly define it (i.e: using -XX:+UseParallelGC)
  • Revisit your current JVM GC options to be in line with G1
  • Verify your applications performance has not degraded

Removal of GC Flag Combinations

Some rarely used JVM Garbage Collection combinations have been removed (mainly related to CMS – Concurrent Mark Sweep). As such, there will be no replacements for them since the remaining collectors should perform at least as well or better than what was attainable with those combinations.

Are you still using any of the following combinations as JVM startup flags listed blow?

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

What Should I do? …..

If you have been using the above combinations, they will stop working. and the JVM will not start (no warning message). But you now have been warned! So remove them before the lack of feedback leaves you scratching you head.

More info here JEP 214: Remove GC Combinations

Bye-Bye Perm Gen … for real!

The permanent generation holds the Class metadata, internal Strings and class static variables; sound familiar?! Their now moving Strings and statics over to the Java heap and Class metadata to native memory. This is a serious modification.

What Should I do? …..

  • Remove the MaxPermSize JVM option from your tools/scripts (i.e: dumping JVM’s String literal pool) that have knowledge of the perm gen space.
  • Possibly have to adjust our Heap space to take on some of this extra load into consideration (i.e increasing -Xmx) .

More info here JEP 122: Remove the Permanent Generation

GC Logging Reimplemented

First of all, this one’s gonna hurt for those of us that have worked with GC log parsers. The Garbage Collection logging has been re-implemented using the Unified JVM Logging framework which means the GC logging format will be different.

To put it into context, I took an excerpt straight from the JEP Agile board

“From what I’ve seen of the new logging format, no GC log messages will stay the same. Each message has a leader that has information such as log level and that will make the format of all messages different from today … We’re going to break parsers so we want to get it right.”

This is happening for a reason right?

Yes! This is going to be of great benefit for diagnostics and figuring the root causes behind problems like JVM crashes. Quite honestly, it’s about time!

 Goodbye to options ...

Say hello to new command-line option –Xlog which introduces a way to control logging from all components of the JVM … awesome!

This is possible through the use of new logging prefixes (tags) which helps categorize log messages for finer grain control. This and other new features will  help us attain a finer level of granularity which was not previously possible without extra tooling.

See Unified JVM Logging – Command-line-options for full details.

Especially relevant is  the “gc” tag ( -Xlog:gc ; the default) which is somewhat similar to what you use to get with -XX:+PrintGCDetails and -XX:+PrintGC. Moving forward, all GC-related logging should use these tags (many tags; classload, compiler etc..).

One or more tags used together are called a tag-set. So using just “gc” may be too broad (defaults to debug INFO level for that category). You’ll most likely combine tags to get what your after.

Advanced Example (fine grained logging):


The above will log messages tagged with at least ‘gc’ and ‘rt’ and ‘compiler’ tag using ‘trace’ level to ‘stdout’ but only log messages tagged with ‘meta’ with level ‘warning’ or ‘error’ and turn off all messages tagged with ‘svc’.

What Should I do? …..

  • Run your parser tools against the new format and to evaluate the impact and level of effort to get it back on its feet.
  • Start taking advantage of the new finer grained control to determine if you can even remove some of your custom parsing/filtering code with the new options available.

More info here JEP 271: Unified GC Logging

GC Tools Removed from JDK 9

  • The JVM TI hprof Agent (can instead use Java VisualVM, jmap, jmd)
  • The jhat heap visualization tool (can instead use Java VisualVM)

The Java VisualVM is no longer bundled with JDK 9 so you’ll have to go get it yourself here VisualVM on GitHub.

Happy Migration!

Leave a Reply

Your email address will not be published.