Most garbage collectors must stop application processing (“stop-the-world”) to determine which objects are still in use, which can be garbage collected and to defragment and compact the memory heap. Pause times increase linearly with memory heap size, so a large heap can lead to noticeable delays for users and poor application performance.

GC Tuning – Some Basics

The majority of time spent tuning garbage collection is in attempts to delay compaction. Since most objects die young, garbage collection can be performed on just the young generation for a while, but eventually old dead objects will need to be reclaimed. You can further delay full GC by keeping track of where old gen objects have been removed and use the freed memory in place. Still, at some point this space will become fragmented and need to be reclaimed. You can try to delay garbage collection as long as possible through tuning, but the reality is you can’t delay it forever.

Eliminating garbage collection pauses and the need for GC tuning

The Zing virtual machine uses Azul’s innovative C4 Collector, which improves application performance and eliminates the need for most GC tuning. With Zing, applications perform consistently over a wide, smooth operating range of heap and GC settings. Another key benefit is that ‘what you test is what you get’, so performance in production matches tested performance.

C4 is a highly concurrent, consistent algorithm that is able to concurrently compact the Java heap, and to allow the application to continue to execute while remapping of memory is performed. Other JVMs require ‘stop-the-world’ pauses to fully compact the heap. See the comparison of Zing GPGC and the HotSpot JVM’s CMS below.

Comparison of HotSpot JVM CMS and Zing Pauseless Garbage Collection

HotSpot JVM CMS Azul Pauseless Garbage Collection
  • Stop-the-world compacting new gen (ParNew)
  • Concurrent, compacting new generation
  • Mostly concurrent, non-compacting old gen (CMS)
    • Mostly Concurrent marking
      • Mark concurrently while mutator is running
      • Track mutations in card marks
      • Revisit mutated cards (repeat as needed)
      • Stop-the-world to catch up on mutations, ref processing, etc.
    • Concurrent sweeping
    • Does not compact (maintains free list, does not move objects)
  • Concurrent, compacting old generation
  • Concurrent guaranteed-single-pass marker
    • Oblivious to mutation rate
    • Concurrent ref (weak, soft, final) processing
  • Concurrent Compactor
    • Objects moved without stopping mutator
    • Can relocate entire generation (new, old) in every GC cycle
  • Fallback to full collection (stop the world)
    • Used for compaction, etc.
  • No stop-the-world fallback
    • Always compacts, and does so concurrently

Next steps: 

Garbage Collection (GC) measurement considerations

It’s important to measure the actual application rather than performing synthetic tests (garbage in, garbage out). As a general rule of thumb, you should see more than 5 ‘bad’ garbage collection pauses during the test period, otherwise, you did not test real behavior. (Note, too, that most industry benchmarks are tuned to avoid garbage collection pauses during test.) Test until you can show garbage collection is stable (e.g. what if it trends up over time?). Some basic suggestions for good GC measurement tests:

  • Generally aim for 20-30 minute “stable load” tests
  • Don’t “ramp” load during test period – it will defeat the purpose
  • Add low-load noise to trigger “real” GC behavior (see Azul’s “Fragger” example)
  • Download the open source jHiccup tool for accurate measurements of Java pauses or ‘hiccups’

© Azul Systems, Inc. 2017 All rights reserved.