JDK-8264420 : Allow MonitorUsedDeflationThreshold=0 for aggressive deflation of all eligible monitors
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 15,16,17
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • Submitted: 2021-03-30
  • Updated: 2024-04-11
  • Resolved: 2024-04-11
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
I have been rewriting JOL samples for modern JDKs, and one of the things I noticed after JDK-8153224 work is that there seem to be no way to request deflating all unused monitors.

There is MonitorUsedDeflationThreshold which drives the deflation, but MonitorUsedDeflationThreshold=0 means "disabled". So, it is somewhat problematic for the test that has only one unused monitor to handle, which never meets the non-zero MonitorUsedDeflationThreshold threshold. 

There also used to be the escape hatch to get the previous safepoint-based deflation behavior, by setting -XX:-AsyncDeflateIdleMonitors, but it was removed with JDK-8246476.

Rewiring the "deflation is disabled" to, say, -1, and allow rounding to match the zero threshold gives the -XX:MonitorUsedDeflationThreshold=0 the meaning of "deflate all you can".

diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index 049652904ca..4afe9249f9f 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -728,7 +728,7 @@ const intx ObjectAlignmentInBytes = 8;
           range(1024, max_jint)                                             \
                                                                             \
   product(intx, MonitorUsedDeflationThreshold, 90, EXPERIMENTAL,            \
-          "Percentage of used monitors before triggering deflation (0 is "  \
+          "Percentage of used monitors before triggering deflation (-1 is " \
           "off). The check is performed on GuaranteedSafepointInterval "    \
           "or AsyncDeflationInterval.")                                     \
           range(0, 100)                                                     \
diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp
index a67da9147b3..014c1b96cfe 100644
--- a/src/hotspot/share/runtime/synchronizer.cpp
+++ b/src/hotspot/share/runtime/synchronizer.cpp
@@ -1074,7 +1074,7 @@ void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure) {
 }
 
 static bool monitors_used_above_threshold(MonitorList* list) {
-  if (MonitorUsedDeflationThreshold == 0) {  // disabled case is easy
+  if (MonitorUsedDeflationThreshold == -1) {  // disabled case is easy
     return false;
   }
   // Start with ceiling based on a per-thread estimate:
@@ -1102,7 +1102,7 @@ static bool monitors_used_above_threshold(MonitorList* list) {
 
   // Check if our monitor usage is above the threshold:
   size_t monitor_usage = (monitors_used * 100LL) / ceiling;
-  return int(monitor_usage) > MonitorUsedDeflationThreshold;
+  return int(monitor_usage) >= MonitorUsedDeflationThreshold;
 }
 
I think this also allows more aggressive testing of async deflation.
Comments
Reclosing as "Duplicate" instead of Resolving as...
11-04-2024

This is no longer a problem after JDK-8305994 introduced -XX:GuaranteedAsyncDeflationInterval. The relevant JOL sample (JOLSample_14_FatLocking) works well with it.
10-04-2024

Link related bug.
07-05-2021