Uncommit delay option

Holger Hoffstätte holger at applied-asynchrony.com
Sat Oct 12 13:33:15 UTC 2019


On 10/12/19 2:03 PM, Stefan Reich wrote:
> Hi,
> 
> I'm still looking for the perfect garbage collector. Went with G1 for a
> long time - and happily. Then ZGC was tried, but Linux's problems with
> correctly reporting multi-mapped memory are a real problem. Thus now
> Shenandoah!
> 
> My question regards this article:
> https://shipilev.net/jvm/anatomy-quarks/21-heap-uncommit/ from the
> absolutely excellent JVM Anatomy Quarks series (best JVM coder pr0n I have
> read in a long time).
> 
> The article talks about uncommitting memory after 5 seconds. I want to try
> that, but can't find the option for it. I'm using JDK 13. I ship to end
> users, so keeping memory use compact is essential.

The option is called ShenandoahUncommitDelay (in milliseconds), e.g.
-XX:ShenandoahUncommitDelay=60000 will try to uncommit every minute.
Note that this doesn't *guarantee* RSS shrinking on every interval;
it might take a concurrent cycle or two for regions to be compact
enough.

In JDK13 the default is 300000 (5 minutes), when you set the "compact"
heuristic via -XX:ShenandoahGCHeuristics=compact it is automatically set
to 1000 aka 1 second. I personally find this a bit too aggressive/overhead-y
and use the above 60000; constantly shrinking the heap only to regrow it
a second later is not helpful.

Another and IMHO much more useful trick for generational workloads is
IMHO to make sure ShenandoahAllocationThreshold is set "properly", meaning
how much allocation (in terms of max. heap %) you want to allow before
scheduling a concurrent cycle. By default (i.e. without compact profile)
Shenandoah is great for heaps with large-ish residency, but less so for
small heaps with slow-but-constant allocation that keeps residency
unintentionally high between ShenandoahGuaranteedGCInterval cycles
(very annoying e.g. with apps that do I/O via NIO and fill the heap with
useless buffers, assuming a traditional nursery-style GC instead of
recycling themselves). Setting the allocation threshold as part of compact
will prevent this, at the cost of more frequent concurrent cycles.

The benefit here is the ability to allow for very large -Xmx heaps when
required, but cruise along with much smaller heaps before and after large
outlier allocations. Whether this is something you want to allow is for
you to decide.

You can verify the default values and how they change with the different
heuristics via -XX:+PrintFlagsFinal.

In my experience Shenandoah is currently the only GC that does all these
things properly and as expected (as of JDK13).

hth,
Holger


More information about the shenandoah-dev mailing list