[java] Difference between -XX:+UseParallelGC and -XX:+UseParNewGC

They are algorithms for the young generation garbage collection.

The second one (UseParNewGC) gets activated automatically with the concurrent tenured generation garbage collection (see Java Concurrent and Parallel GC) but, is there a difference between the two parallel algorithms?

This question is related to java jvm-arguments

The answer is


Using -XX:+UseParNewGC along with -XX:+UseConcMarkSweepGC, will cause higher pause time for Minor GCs, when compared to -XX:+UseParallelGC.

This is because, promotion of objects from Young to Old Generation will require running a Best-Fit algorithm (due to old generation fragmentation) to find an address for this object.
Running such an algorithm is not required when using -XX:+UseParallelGC, as +UseParallelGC can be configured only with MarkandCompact Collector, in which case there is no fragmentation.


Parallel GC

  • XX:+UseParallelGC Use parallel garbage collection for scavenges. (Introduced in 1.4.1)
  • XX:+UseParallelOldGC Use parallel garbage collection for the full collections. Enabling this option automatically sets -XX:+UseParallelGC. (Introduced in 5.0 update 6.)

UseParNewGC

UseParNewGC A parallel version of the young generation copying collector is used with the concurrent collector (i.e. if -XX:+ UseConcMarkSweepGC is used on the command line then the flag UseParNewGC is also set to true if it is not otherwise explicitly set on the command line).

Perhaps the easiest way to understand was combinations of garbage collection algorithms made by Alexey Ragozin

_x000D_
_x000D_
<table border="1" style="width:100%">_x000D_
  <tr>_x000D_
    <td align="center">Young collector</td>_x000D_
    <td align="center">Old collector</td>_x000D_
    <td align="center">JVM option</td>_x000D_
  </tr>_x000D_
  <tr>_x000D_
    <td>Serial (DefNew)</td>_x000D_
    <td>Serial Mark-Sweep-Compact</td>_x000D_
    <td>-XX:+UseSerialGC</td>_x000D_
  </tr>_x000D_
  <tr>_x000D_
    <td>Parallel scavenge (PSYoungGen)</td>_x000D_
    <td>Serial Mark-Sweep-Compact (PSOldGen)</td>_x000D_
    <td>-XX:+UseParallelGC</td>_x000D_
  </tr>_x000D_
  <tr>_x000D_
    <td>Parallel scavenge (PSYoungGen)</td>_x000D_
    <td>Parallel Mark-Sweep-Compact (ParOldGen)</td>_x000D_
    <td>-XX:+UseParallelOldGC</td>_x000D_
  </tr>_x000D_
  <tr>_x000D_
    <td>Serial (DefNew)</td>_x000D_
    <td>Concurrent Mark Sweep</td>_x000D_
    <td>_x000D_
      <p>-XX:+UseConcMarkSweepGC</p>_x000D_
      <p>-XX:-UseParNewGC</p>_x000D_
    </td>_x000D_
  </tr>_x000D_
  <tr>_x000D_
    <td>Parallel (ParNew)</td>_x000D_
    <td>Concurrent Mark Sweep</td>_x000D_
    <td>_x000D_
      <p>-XX:+UseConcMarkSweepGC</p>_x000D_
      <p>-XX:+UseParNewGC</p>_x000D_
    </td>_x000D_
  </tr>_x000D_
  <tr>_x000D_
    <td colspan="2">G1</td>_x000D_
    <td>-XX:+UseG1GC</td>_x000D_
  </tr>_x000D_
</table>
_x000D_
_x000D_
_x000D_

Conclusion:

  1. Apply -XX:+UseParallelGC when you require parallel collection method over YOUNG generation ONLY, (but still) use serial-mark-sweep method as OLD generation collection
  2. Apply -XX:+UseParallelOldGC when you require parallel collection method over YOUNG generation (automatically sets -XX:+UseParallelGC) AND OLD generation collection
  3. Apply -XX:+UseParNewGC & -XX:+UseConcMarkSweepGC when you require parallel collection method over YOUNG generation AND require CMS method as your collection over OLD generation memory
  4. You can't apply -XX:+UseParallelGC or -XX:+UseParallelOldGC with -XX:+UseConcMarkSweepGC simultaneously, that's why your require -XX:+UseParNewGC to be paired with CMS otherwise use -XX:+UseSerialGC explicitly OR -XX:-UseParNewGC if you wish to use serial method against young generation

UseParNewGC usually knowns as "parallel young generation collector" is same in all ways as the parallel garbage collector (-XX:+UseParallelGC), except that its more sophiscated and effiecient. Also it can be used with a "concurrent low pause collector".

See Java GC FAQ, question 22 for more information.

Note that there are some known bugs with UseParNewGC