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

Stephen Felts stephen.felts at oracle.com
Sun Apr 16 20:45:40 UTC 2017


When we did testing of G1 with SpecEnterprise2010 on JDK8, we saw measurably lower performance.  While this is a known benchmark, most or our internal benchmarks also saw lower performance.

Work was done by the JDK team to improve that.  Looking for the externally available bugs:

 

https://bugs.openjdk.java.net/browse/JDK-8065281 Avoid G1 write barriers on newly allocated objects - did not make it into JDK 8.

 

https://bugs.openjdk.java.net/browse/JDK-8020306 G1: Minor Collections are 2x longer than Throughput collections  - I think this made it into JDK 8 u40.  If you can't see this bug, you might be able to see these related bugs.

I see that some of these bugs are still open.

 

Issue Links

duplicates

Bug - A problem which impairs or prevents the functions of the product.HYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8022038"JDK-8022038 REGRESSION: G1 minor collections 2s longer than throughput collector 

Bug - A problem which impairs or prevents the functions of the product.HYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8022038"JDK-8022038 REGRESSION: G1 minor collections 2s longer than throughput collector 

 

relates to

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8027547"JDK-8027547 G1 should not push already forwarded objects into the object task queue but special case them 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8027551"JDK-8027551 Add fast path checking whether an object is scavengable in g1 oop scan closures 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8027761"JDK-8027761 Investigate fast-path for scanning only objects with references during gc 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8027545"JDK-8027545 Improve object array chunking test in G1's copy_to_survivor_space 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8030144"JDK-8030144 Class loader data graph scanning causes high termination time 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8030860"JDK-8030860 Initial mark time should be anticipated in G1 young gen sizing 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8040120"JDK-8040120 Long delays during GC pause in G1 in some situations 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8034842"JDK-8034842 Parallelize the Free CSet phase in G1 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8027553"JDK-8027553 Change the in_cset_fast_test functionality to use the G1BiasedArray abstraction 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8027559"JDK-8027559 Decrease code size and templatizing in G1ParCopyClosure::do_oop_work 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8027295"JDK-8027295 Free CSet takes ~50% of young pause time 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8027746"JDK-8027746 Remove do_gen_barrier template parameter in G1ParCopyClosure 

Enhancement - nullHYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8027554"JDK-8027554 Implicit in-heap check in G1CollectedHeap::in_cset_fast_test() not always required 

 

 

 

 

 

-----Original Message-----
From: Thomas Schatzl 
Sent: Sunday, April 16, 2017 12:27 PM
To: Ben Evans
Cc: jdk9-dev at openjdk.java.net
Subject: Re: JEP 291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector

 

Hi Ben,

 

On Sun, 2017-04-16 at 12:38 +0100, Ben Evans wrote:

> Hi Thomas,

> 

> I'm very glad the community has been able to provide an example of an 

> experimental configuration that's able to meet your publicised claims

> - and all it took was unlocking experimental options and several

 

  use of the experimental options is not required in this case. They may be convenient to use, but not necessary.

 

The used experimental options are -XX:G1NewSizePercent -XX:G1MaxNewSizePercent and -XX:G1MixedGCCountTarget:

 

*) -XX:G1NewSizePercent -XX:G1MaxNewSizePercent can be substitued by appropriate values for -XX:NewSize and -XX:MaxNewSize. I have seen people using these ones with other collectors for exactly the same purpose, i.e. keep young gen large.

 

*) The only experimental option left is

-XX:G1MixedGCLiveThresholdPercent, but this one's effect could be substituted by the product flag -XX:G1MixedGCCountTarget.

 

The new and updated documentation explains the use of all these options in more detail [1].

 

So there is almost certainly no need at all to use experimental options in this case, neither in JDK 8u nor in JDK 9.

 

This does not mean we think G1 is perfect: ideally it would meet the pause time requirement without any of these extra options. So we are working on CRs like JDK-8159697 [6] to make G1 out-of-the-box experience even better in the future.

 

In comparison point, CMS runs into unacceptable long pauses (Full GCs) in this workload.

 

As for the other "unusual" product options:

 

*) Setting the value of -XX:InitiatingHeapOccupancyPercent seems to be purely for throughput optimization purposes to keep young gen really big all the time. The old gen occupancy in the logs is never even close to being exhausted (like ~2g out of 10g). The default value of 45 should be sufficient.

 

Also, beginning with JDK 9 G1 automatically calculates an optimal value for this flag like CMS. From our experience G1's and probably CMS's heuristics yield better results than an average person, achieving higher throughput at no other costs.

 

It is certainly possible to improve upon these heuristics with both collectors, if so, the options are there to allow you to try.

 

Some more notes about other unusual options:

 

*) As for using TargetSurvivorRatio to keep objects in the young gen, I am not completely convinced that it actually makes a lot of difference.

One could use either -XX:SurvivorRatio or -XX:+NeverTenure instead to keep objects longer or as long as possible in the survivor generation.

At least I have seen -XX:SurvivorRatio being used in CMS.

 

*) -XX:G1HeapRegionSize seems to be the only one that seems specific to the application and G1 and may be required. It is a bit unusual to use this if the old gen occupancy is that low - but it may be provide some improvement.

 

The other options are neither unusual nor specific to G1 (Xms==Xmx, AlwaysPreTouch, UseLargePages, ...). They are typical options you use when you want to tune for throughput for any collector.

 

Please be aware that these comments are based on the very coarse logs provided without any deeper analysis, so I may be wrong.

 

> months of tuning work!

 

I do not see a difference between required tuning effort for CMS and G1, except that there may be more experience in the community with CMS.

It may be harder for you (assuming you have been using CMS for years), but the argument also works the other way.

 

As for learning to use G1, we significantly revised the official documentation for G1. It and the accompanying tuning guide for G1 seems to be significantly more comprehensive than the one for CMS has ever been now.

This should provide anyone new or moving to G1 tuning a significant headstart. In the future there will (hopefully) be no more need for unexplained lists of magic CMS/G1 options from somewhere on the internet.

 

As for actual time taken to tune an application, I am really not the best person to ask: in my experience, tuning G1 is much less painful than CMS, there are much less options to use that make a difference, and the initial out-of-box results are typically better. However my applications and requirements are probably different than what you are looking at.

 

Please, if you have issues with G1 (or any other collector), join the hotspot-gc-use mailing list and contribute your experience.

 

> However, if I'm reading your mail correctly, your point is that the 

> version of G1 that will be delivered & made default in Java 9 is 

> substantially different from anything that has been seen so far in 

> shipping versions of Java 8?

 

The changes in JDK9 change the performance profile in regards to startup, footprint, throughput and latency. These metrics will be different particularly out-of-the-box than in JDK 8u. The reasons are evolutionary optimization (or sometimes only changing some default values more adapted to current applications).

 

Please see the JavaOne G1 presentation for some more details [3].

 

The collector itself and its mechanics did not change at all. E.g. the current documentation (and tuning guide) for G1 except for minor details (like default values, maybe some option renaming) also applies to JDK 8.

 

This seems natural for a change of any software from one major version to another, given that there have been more than two years of time between now and JDK 8u40 that JEP 248 [2] references [4].

 

These changes were also guided by feedback from the community, like making particularly time consuming tuning automatic (e.g. adaptive sizing of IHOP [5]) or others.

 

We will continue making G1 perform better particularly out-of-the box (e.g. the mentioned parallel full gc). So I am likely correct to say that the performance profile of G1 in JDK 10 at its release will be different from anything seen in JDK 9 at its release again, substantially for some cases. I assume that there will be EA releases again for the community to test long before release though.

 

> Is that correct? Oracle are planning to make default a GC which has 

> had, essentially, zero testing on actual production workloads?

 

Making G1 default collector has different reasons than suggesting it as CMS replacement. It affects different users, and different applications. This has been discussed before, see the JEP 248 discussion on this mailing list.

 

The "new" G1 has been available for testing by the community since the start of JDK 9 EA releases around three years ago. At least some Linux distros provide OpenJDK 9 packages for some time now. So anyone can grab a copy at any time, test their application on them, and provide feedback. We are always happy to help with issues.

 

Internally, we have been continuously performance and regression testing G1 for all that time, adding tests and flushing out bugs cropping up.

 

Some open source projects have made G1 default with JDK 8(u) already, or provide settings for using their project with G1. There have been no negative reports that were not fixed I am aware of from people using G1 switching from JDK 8 to JDK 9. I guess there will be some more reports when JDK 9 launches, but this does not seem anything unusual for such a complex piece of software.

 

Products switching from JDK 8 to JDK 9 that use CMS will still be able to use CMS as before in JDK 9. Regardless of GC I recommend testing before going into production.

 

What I am asking is, if you are using CMS, please give G1 a try with JDK 9 (or even JDK 8u) and contribute feedback. If you unsuccessfully tried G1 with JDK 8u, please give it another look, it may fit your needs with JDK 9. We are also of course always very happy hearing about success stories with G1 :)

 

Thanks,

  Thomas

 

[1] https://docs.oracle.com/javase/9/gctuning/garbage-first-garbage-col

lector-tuning.htm#JSGCT-GUID-90E30ACA-8040-432E-B3A0-1E0440AB556A

(Please, if you have time, have a look and give feedback. It collects a lot of experience and feedback from the community but we are aware that it may need further improvements!) [2] http://openjdk.java.net/jeps/248 [3] https://oracle.rainfocus.com/scripts/catalog/oow16.jsp?event=javaon

e&search=CON3889&search.event=javaone

[4] https://www.java.com/en/download/faq/release_dates.xml

[5] https://bugs.openjdk.java.net/browse/JDK-8136677

[6] https://bugs.openjdk.java.net/browse/JDK-8159697

 


More information about the jdk9-dev mailing list