Of course the re-size can only happen to the "upper-bound" (-Xmx
) of your heap, so the max value is still respected. But a garbage collector can make that smaller, yes. As well as it can grow from -Xms
.
In general, there are cases when you really want your garbage collector to re-size the heap. kubernetes
is such an environment, for example. kubernetes does not have swap, so when you fill up the RAM, pods will start to be killed. Now if your pods have a setting of -Xmx10g
and at some point they really used this much, but currently only use 1GB
, for kubernetes, they still consume 10GB
. To put it simpler, there are 9GB
that some pod does not need nor use right now, but java GC
will not handle those back.(more details here). This is where re-sizing the heap might come handy.
G1GC
always could give memory back to the OS (re-size to a smaller heap), here is an example, but until java-12 and this JEP, it would only very, very rarely do that. Other garbage collector algorithms (like Shenandoah
), will give memory back to the OS faster, for example.
While this might be an advantage in some cases, it comes at a price. un-commit
the pages (or resize) is not a free process. Then, the heap is not only used for your allocations of new instances, but also for the GC work itself. When G1
has to copy live objects to different regions, it still uses the heap space for copying from region to region. Then there are internal GC
structures that can use the heap too, like SATB
queues, etc.
Then there is the fact that because some steps in the GC work are concurrent, you need a heap big enough to cover that delta or newly allocated objects while the concurrent phase is in flight. In general, the more heap you have (the more breathing room a GC
has), the better your application will behave.