When to choose SerialGC, ParallelGC over CMS, G1 in Java?
Asked Answered
U

3

48

In Java 9, G1 GC is the default Garbage collector. As of now, I heard of some people preferring CMS garbage collector over G1GC as it seems to be not stable and has some nasty bugs.

What happened with ParallelGC (no buzz these days) ? Is there any use case in which we would like to prefer ParallelGC over CMS/G1 ?

Also, is there any case where SerialGC could out perform all these parallel collectors ?

Uranus answered 10/2, 2019 at 11:30 Comment(2)
AFAIK SerialGC can be used if it is critical for the application to consume as less native memory as possible since along with Shenandoah GC it has one of the smallest overhead.Zoography
G1GC is stable in current Java releases. You are looking at recommendations in an older version of the ElasticSearch documentation. But you should NOT be using Java 9 because it is EOL. And I guess that means that any new bug fixes for G1GC in other versions won't be ported to Java 9.Subulate
B
36

Serial collector

Mainly for single-cpu machine.

Algorithm:

It use a single thread to handle heap, and perform stop-the-world pause during any gc. Just see it as toy.

This is default for client-class machine (32bit jvm on windows or single-cpu machine).


Parallel collector

Algorithm:

It uses multiple gc threads to handle heap, and perform stop-the-world pause during any gc.

<= Java 8, this is default for server-class machine (multi-cpu unix-like machine or any 64bit jvm).


CMS collector

It's designed to eliminate the long pause associated with the full gc of parallel & serial collector.

Algorithm:

It use 1 or more gc threads to scan the old generation periodically, and discard unused objects, the pause is very short, but use more cpu time.

Warning: since Java 14, it's removed.


G1 collector

It's low pause / server style gc, mainly for large heap (> 4Gb).

Algorithm:

  • Similar as CMS, it use multiple background gc threads to scan & clear heap.
  • It divide old generation into parts, it could clean old generation by copy from 1 part to another.
    Thus it's less possible to get fragmentation.

Since Java 9, this is default for server-class machine (multi-cpu unix-like machine or any 64bit jvm).


Why use G1 as default?

The main reason is to reduce the gc pause time, though the overall throughput might be reduced.

Butch answered 10/2, 2019 at 18:53 Comment(2)
Ok. But when to use which algorithm ? Let's say my app requires 2 core cpu machine and 1 GB of heap. Should I use parallel, CMS or G1 ?Uranus
I think both CMS and G1 will work for sure. And parallel probably is good enough too. If your application is real-time (e.g a trading system), and need very low pause, then use G1 or CMS (for me G1 is the choice), otherwise you can also use parallel collector. For a small application like this, it doesn't matter that much. Probably what's more important is to enable the gc log with rotation, check it when issue occur, and also with the help of tools like visualvm, of built-in command jmap, jcmd. Then switch a collector if need. If you don't bother to check the details, just use G1.Butch
G
19

You can read the documentation Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide-Java9

  • Serial Collector

    It's best-suited to single processor machines because it can't take advantage of multiprocessor hardware, although it can be useful on multiprocessors for applications with small data sets (up to approximately 100 MB).

  • Parallel Collector

    The parallel collector is also known as throughput collector, it's a generational collector similar to the serial collector. The primary difference between the serial and parallel collectors is that the parallel collector has multiple threads that are used to speed up garbage collection. The parallel collector is intended for applications with medium-sized to large-sized data sets that are run on multiprocessor or multi-threaded hardware. If you don't care about pause time and prefer to throughput, this collector would be best.

  • The Mostly Concurrent Collectors(CMS)

This collector is deprecated in Java9.

This collector is for applications that prefer shorter garbage collection pauses and can afford to share processor resources with the garbage collection.

  • G1 garbage collector

    This server-style collector is for multiprocessor machines with a large amount of memory. It meets garbage collection pause-time goals with high probability, while achieving high throughput.

summary:

  • If the application has a small data set (up to approximately 100 MB), then select the serial collector with the option -XX:+UseSerialGC.

  • If the application will be run on a single processor and there are no pause-time requirements, then select the serial collector with the option -XX:+UseSerialGC.

  • If (a) peak application performance is the first priority and (b) there are no pause-time requirements or pauses of one second or longer are acceptable, then let the VM select the collector or select the parallel collector with -XX:+UseParallelGC.

  • If response time is more important than overall throughput and garbage collection pauses must be kept shorter than approximately one second, then select a concurrent collector with -XX:+UseG1GC or -XX:+UseConcMarkSweepGC.

Q&A:

  1. I heard of some people preferring CMS garbage collector over G1GC as it seems to be not stable and has some nasty bugs.

The G1 collector is stable enough for most applications. I used G1 collector for many applications, and all of them work well. If you can upgrade java9 to Java11, it work better and bugs are less.

  1. Is there any use case in which we would like to prefer ParallelGC over CMS/G1?

Yes. Some applications which need more throughput and don't care about pause time using parallel collector would be better. For instance, batch tasks, offline jobs, calculate tasks.

  1. Also, is there any case where SerialGC could out perform all these parallel collectors ?

If you run JVM on embedded system, or some system which has one or two CPU, the Serial GC would be better.

Finally, G1 VS CMS: In most case, G1 can replace CMS. And in such case, you'd better use G1:

  1. You have a big heap, like 16G. There is a positive correlation between pause time and heap size.On the contrary, G1 is incremental collector.
  2. You have strict pause time requirement and want more controllable for pause time. Like, you want the pause time <=10ms.
Greige answered 12/2, 2019 at 3:53 Comment(0)
M
0

Use Serial :
- only 1CPU available and no pause requirements are there - small JVMs are present on single machine (more than number of CPUs) - small live data set (less than 100MB)

Use Parallel:
- non interative batch application where application performance is important than low pause times

Mortenson answered 23/12, 2019 at 11:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.