1 /* 2 * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/javaClasses.hpp" 27 #include "classfile/vmClasses.hpp" 28 #include "classfile/vmSymbols.hpp" 29 #include "logging/log.hpp" 30 #include "logging/logStream.hpp" 31 #include "memory/universe.hpp" 32 #include "runtime/interfaceSupport.inline.hpp" 33 #include "runtime/java.hpp" 34 #include "runtime/javaCalls.hpp" 35 #include "runtime/monitorDeflationThread.hpp" 36 #include "runtime/mutexLocker.hpp" 37 #include "runtime/synchronizer.hpp" 38 39 void MonitorDeflationThread::initialize() { 40 EXCEPTION_MARK; 41 42 const char* name = "Monitor Deflation Thread"; 43 Handle thread_oop = JavaThread::create_system_thread_object(name, CHECK); 44 45 MonitorDeflationThread* thread = new MonitorDeflationThread(&monitor_deflation_thread_entry); 46 JavaThread::vm_exit_on_osthread_failure(thread); 47 48 JavaThread::start_internal_daemon(THREAD, thread, thread_oop, NearMaxPriority); 49 } 50 51 void MonitorDeflationThread::monitor_deflation_thread_entry(JavaThread* jt, TRAPS) { 52 53 // We wait for the lowest of these three intervals: 54 // - GuaranteedSafepointInterval 55 // While deflation is not related to safepoint anymore, this keeps compatibility with 56 // the old behavior when deflation also happened at safepoints. Users who set this 57 // option to get more/less frequent deflations would be served with this option. 58 // - AsyncDeflationInterval 59 // Normal threshold-based deflation heuristic checks the conditions at this interval. 60 // See is_async_deflation_needed(). 61 // - GuaranteedAsyncDeflationInterval 62 // Backup deflation heuristic checks the conditions at this interval. 63 // See is_async_deflation_needed(). 64 // 65 intx wait_time = max_intx; 66 if (GuaranteedSafepointInterval > 0) { 67 wait_time = MIN2(wait_time, GuaranteedSafepointInterval); 68 } 69 if (AsyncDeflationInterval > 0) { 70 wait_time = MIN2(wait_time, AsyncDeflationInterval); 71 } 72 if (GuaranteedAsyncDeflationInterval > 0) { 73 wait_time = MIN2(wait_time, GuaranteedAsyncDeflationInterval); 74 } 75 76 // If all options are disabled, then wait time is not defined, and the deflation 77 // is effectively disabled. In that case, exit the thread immediately after printing 78 // a warning message. 79 if (wait_time == max_intx) { 80 warning("Async deflation is disabled"); 81 return; 82 } 83 84 while (true) { 85 { 86 // Need state transition ThreadBlockInVM so that this thread 87 // will be handled by safepoint correctly when this thread is 88 // notified at a safepoint. 89 90 ThreadBlockInVM tbivm(jt); 91 92 MonitorLocker ml(MonitorDeflation_lock, Mutex::_no_safepoint_check_flag); 93 while (!ObjectSynchronizer::is_async_deflation_needed()) { 94 // Wait until notified that there is some work to do. 95 ml.wait(wait_time); 96 } 97 } 98 99 (void)ObjectSynchronizer::deflate_idle_monitors(); 100 101 if (log_is_enabled(Debug, monitorinflation)) { 102 // The VMThread calls do_final_audit_and_print_stats() which calls 103 // audit_and_print_stats() at the Info level at VM exit time. 104 LogStreamHandle(Debug, monitorinflation) ls; 105 ObjectSynchronizer::audit_and_print_stats(&ls, false /* on_exit */); 106 } 107 } 108 }