The trigger of _codecache_GC_threshold in CodeCache::gc_on_allocation is the 
key to this problem.

if (used_ratio > threshold) {
    // After threshold is reached, scale it by free_ratio so that more 
aggressive
    // GC is triggered as we approach code cache exhaustion
    threshold *= free_ratio;
  }
  // If code cache has been allocated without any GC at all, let's make sure
  // it is eventually invoked to avoid trouble.
  if (allocated_since_last_ratio > threshold) {
    // In case the GC is concurrent, we make sure only one thread requests the 
GC.
    if (Atomic::cmpxchg(&_unloading_threshold_gc_requested, false, true) == 
false) {
      log_info(codecache)("Triggering threshold (%.3f%%) GC due to allocating 
%.3f%% since last unloading (%.3f%% used -> %.3f%% used)",
                          threshold * 100.0, allocated_since_last_ratio * 
100.0, last_used_ratio * 100.0, used_ratio * 100.0);
      Universe::heap()->collect(GCCause::_codecache_GC_threshold);
    }
  }

Here with the limited codecache size, the free_ratio will get lower and lower 
(so as the threshold) if no methods can be swept and thus leads to a more and 
more frequent collection behavior. Since the collection happens in stw, the 
whole performance of gc will also be degraded. 

So a simple solution is to delete the scaling logic here. However, I think here 
lies some problems worth further exploring.

There're two options to control a code cache sweeper,  
StartAggressiveSweepingAt and SweeperThreshold.  StartAggressiveSweepingAt is a 
sweeper triggered for little space in codeCache and does little harm. However,  
SweeperThreshold, first introduced by 
[JDK-8244660](https://bugs.openjdk.org/browse/JDK-8244660), was designed for a 
regular sweep for codecache, when codeCache sweeper and heap collection are 
actually individual. After 
[JDK-8290025](https://bugs.openjdk.org/browse/JDK-8290025) and some patches 
related, the old mechanism of codeCache sweeper is merged into a concurrent 
heap collection. So the Code cache sweeper heuristics and the unloading 
behavior will be promised by the concurrent collection. There's no longer any 
"zombie" methods to be counted. Considering it will introduce lots of useless 
collection jobs, I think SweeperThreshold should be deleted now.

-------------

Commit messages:
 - remove SweeperThreshold and set it to Obselete

Changes: https://git.openjdk.org/jdk/pull/21084/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=21084&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8340434
  Stats: 55 lines in 14 files changed: 1 ins; 53 del; 1 mod
  Patch: https://git.openjdk.org/jdk/pull/21084.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/21084/head:pull/21084

PR: https://git.openjdk.org/jdk/pull/21084

Reply via email to