ClassUnloadingWithConcurrentMark

Aleksey Shipilev shade at redhat.com
Tue Oct 1 11:11:46 UTC 2019


On 10/1/19 12:50 PM, Simone Bordet wrote:
> I'm a bit confused by this flag so I'd like some clarification.

The description is:
                                                                            \
  product(bool, ClassUnloadingWithConcurrentMark, true,                     \
          "Do unloading of classes with a concurrent marking cycle")        \

This is not Shenandoah-specific. G1 reacts to it as well. Both G1 and Shenandoah do the same thing
there: do not directly visit "weak" roots during mark, and at final mark pause see what weak roots
were not visited, and infer from there which classes are dead and can be unloaded.

The actual unloading work happens during the pause, and adds to latency. Which is why Shenandoah
does not do it by default with normal concurrent cycles, and asks users to opt-in to that with
+ClassUnloadingWithConcurrentMark. Recovery paths (degenerated/full gc) or special explicit GC
requests (like Metadata GC request) would do this to unload classes even without this opt-in. (That
can be disabled by the global -ClassUnloading kill switch).

> AFAIU, it's recently (JDK 9+?) possible to do class unloading without being at a safepoint. There
> is now a lock for the ClassLoaderDataGraph that can be grabbed outside safepoint to do class
> unloading.

There is so much more to class unloading than grabbing the lock to CLDG. IIRC, a lot of work went
into runtime in JDK 12 to make fully concurrent class unloading happen.

> Do I understand right that Shenandoah does class unloading
> "concurrently", i.e. without being at a safepoint?

Shenandoah does it concurrently only in sh/jdk, that work is stabilizing, but not yet in mainline.

-- 
Thanks,
-Aleksey



More information about the shenandoah-dev mailing list