Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8282834

Shenandoah Generational: Improve Adaptive Shenandoah Heuristics: optimize back-to-back GC



    • gc
    • generic
    • generic


          1. When one GC pass finishes, control normally flows to idle state. After some time, the control thread checks whether we should start another GC.
          2. The context switching from GC cleanup safetpoint to GC idle state to GC init safepoint is costly because we require all service threads to startup execution and then immediately shut themselves down for safepoint coordination.
          3. The polling delay while GC is idle represents a time during which memory allocations are not being paced and there will be pent-up demand for allocations if allocations were being stalled during the previous GC pass. So allocation rate may be artificially high during this brief intermission between active GC passes.
          4. In the case that the system is operating under heavy memory allocation workload, throughput is improved by checking should_start_gc() within the cleanup phase and immediately starting the next GC right then if appropriate. This avoids the polling delay and the extra context switches. We can piggyback the init-mark activities on the final-update refs safepoint. While this increases the duration of the combined safepoint, it avoids the much longer stop-the-world pauses that are likely to be triggered when GC is operating under this level of stress. The combined duration of final-update-refs and init-mark may still be shorter than the typical duration of final-mark.

      Motivation is based on the following observations:

      1. Even though configured to poll should_start_gc() every 10 ms, the poll may happen less frequently if the system is heavily loaded. We observed, for example, that the first poll following completion of GC occurred 17 ms after GC finished.
      2. Once should_start_gc() returns true, the GC does not actually start until the requested safepoint is reached. In one case, this was observed to occur 211 ms after the safepoint was requested.
      3. At a high allocation rate of 8 GBytes per second, these delays represent allocation of roughly 2 GBytes. Worse yet, the allocation rate during this brief intermission between GC passes is often much higher than the “average” allocation rate for the service. This is because the many allocation requests that were stalled during the previous GC pass will now run unimpeded.
      4. Whenever the heuristics fail to arrange that GC completes its efforts before the allocation pool has exhausted available memory, we experience long stop-the-world pauses associated with degenerated or full GC.




            Unassigned Unassigned
            kdnilsen Kelvin Nilsen
            0 Vote for this issue
            1 Start watching this issue