Question regarding JEP 8204089 Timely Reducing Unused Committed Memory

Aleksey Shipilev shade at redhat.com
Mon Jun 4 13:13:12 UTC 2018


On 06/04/2018 02:26 PM, Thomas Schatzl wrote:
> Implementing something like Shenandoah, i.e. uncommit the regions that
> stayed empty for more than ShenandoahUncommitDelay milliseconds would
> mean iterating through all regions and check if they are "old" enough
> to uncommit (and do so) at regular intervals in some STW pause. When
> allocating, also give them some sort of timestamp.
> Again, you need to make sure that the regions are looked through in
> some regular interval (either piggy-backing by some existing regular
> pauses or force one).

I am not sure why STW pause is needed. Nor why timestamps on allocation path are needed.

In Shenandoah, region FSM has a few additional states: Empty-Uncommitted, Empty-Committed, Regular,
Humongous. Allocation path makes state transitions a la {Empty-*, Regular} -> Regular, etc. Cleanup
moves reclaimed regions to Empty-Committed, and records the timestamp when that transition happened.
Uncommit does Empty-Committed -> Empty-Uncommitted for all the regions that have a fitting timestamp.

All these transitions are sharing the same mechanics as the allocation path, so it does not require
pause to work. The uncommit checks are done by the concurrent control thread that normally drives
the GC cycle, but also does auxiliary work outside of GC cycle too.

> This would not be particularly hard to implement either, but only seems
> extra work: as you might still want to compact the heap in some way
> (this is optional) by e.g. doing a marking + mixed cycle (and then wait
> for the ShenandoahUncommitDelay), so you may as well uncommit within
> these pauses already.

Periodic GC does indeed help to compact things, but that is a second-order concern. Even
uncommitting the regions that became free after the cycle provides a very substantial win. The
beauty of Shenandoah-style uncommit is that it becomes orthogonal to the GC cycles themselves: you
can first implement uncommits, and then figure out in which form and shape to issue periodic GC
cycles to knock out the rest of the garbage. We might not even bother with that part, and just
instruct users to say -XX:+ExplicitGCInvokesConcurrent, and wait for System.gc() to happen for the
most compaction.

The caveat with piggybacking on pauses, is that you don't really want to uncommit the memory that
would be committed back by allocations in active application. It does make sense to do this on
explicit GC though! You can do this under the pause too, but let's be mindful about the allocation
costs, especially if we are about to commit memory back while holding the allocation lock :)

-Aleksey

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <https://mail.openjdk.org/pipermail/hotspot-gc-dev/attachments/20180604/f2620dfd/signature.asc>


More information about the hotspot-gc-dev mailing list