The Holy Grail: a GC that doesn't need Xmx

alex at alex at
Thu Sep 2 16:32:10 UTC 2021

I did some playing around. Turns out it's kind of expensive to minimize mem usage when there's no young generation. So yeah, I hope you guys finish that)
I made a pass at making ZProactive *actually* proactive: [ ]( ) Mostly it just does a GC whenever the heap grows 20%, but it also tries to choose the number of GC threads.
A -z flag sounds neat, but a tangible metric like, "x MB costs y CPU" is ideal from an economics perspective. Of course, while I'm daydreaming, I should point out that that price can't be held fixed, and an OS-level marketplace should be established where processes and the disk cache can place bids. The real profit, though, will come from letting the user place option trades...
I tried `-J-XX:ShenandoahGCHeuristics=compact` and that didn't actually work very well. My test is to set Xmx to 16GB and launch Netbeans. Shenandoah didn't GC often enough, letting mem usage shoot up 3x the size of the live set. To its credit, it did a commendable job of uncommitting memory. When I wrote my patch, I couldn't figure out how to keep the committed mem from growing unnecessarily (where is this happening?), which of course is the crux of the matter.
Aleksandr Dubinsky
P.S. Kudos on AllocateHeapAt. In my brief testing, it worked surprisingly well just pointing to my SSD (in contrast to regular swapping, which is awful on Linux).
-----Original Message-----
From: "Erik Osterlund" <erik.osterlund at>
Sent: Wednesday, September 1, 2021 9:13am
To: "alex at" <alex at>
Cc: "zgc-dev at" <zgc-dev at>
Subject: Re: The Holy Grail: a GC that doesn't need Xmx

Hi Alex,

I have the same dream, and we can get there with ZGC as we make no algorithmic assumptions about the max size of the heap. I have thought about it and have a few ideas how to get there. Currently, adding a young generation is higher up on the priority list though. But this will likely be revisited. Thanks for letting us know that there is demand for such a feature.


> On 31 Aug 2021, at 21:37, alex at wrote:
> tl;dr I've read zDirector.cpp and played with options, and realized that ZGC can't simply be told to do one job: Keep garbage to a minimum. Why not?
> The schpiel:
> It's long been a dream of mine to run Java apps without giving them a fixed block of RAM to eat (similar to how C/C++ and desktop C# apps work). The usual "here is a fixed block of RAM" was ideal on traditional, dedicated servers but is undesirable on the desktop where apps are expected to play nice under the motto "to each according to their needs." Today, even server apps are moving to a swarming-mass-on-one machine model, thanks to Kubernetes.
> Java on Kubernetes is still a source of frustration. E.g.:
> - [ ]( )
> - [ ]( )
> I don't want this post be about Kubernetes, but juggling Kubernetes soft and hard mem limits, requirements of additional in-container processes, and Java's percent limits, absolute limits, soft and hard limits is non-trivial.
> Problems with current heuristics:
> - ZCollectionInterval doesn't try to stop an allocation spike (such as during startup) from allocating a lot of garbage (and, generally, doesn't try to balance CPU load vs garbage accumulation).
> - A lot of heuristics rely on the value of Max Heap to make decisions, requiring it to be set to a reasonable and small value.
> - Allocating more memory than SoftMaxHeap puts the GC in an endless loop and is very sub-optimal.
> My proposals:
> - Do something else.
> - One idea is to make decisions based solely on how the heap is growing. Eg, trigger GC every 10% of heap growth, and when the heap stops growing trigger by timer.
> - Another (crazier) idea is to make the GC pluggable so that I could register a zDirector on the Java side and do whatever I want.
> - Do anything.
> Thank you for your attention,
> Aleksandr Dubinsky

More information about the zgc-dev mailing list