1 /* 2 * Copyright (c) 2003, 2019, 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/systemDictionary.hpp" 27 #include "classfile/vmSymbols.hpp" 28 #include "memory/resourceArea.hpp" 29 #include "oops/oop.inline.hpp" 30 #include "runtime/handles.inline.hpp" 31 #include "runtime/interfaceSupport.inline.hpp" 32 #include "runtime/java.hpp" 33 #include "runtime/javaCalls.hpp" 34 #include "runtime/mutex.hpp" 35 #include "runtime/mutexLocker.hpp" 36 #include "services/lowMemoryDetector.hpp" 37 #include "services/management.hpp" 38 39 volatile bool LowMemoryDetector::_enabled_for_collected_pools = false; 40 volatile jint LowMemoryDetector::_disabled_count = 0; 41 42 bool LowMemoryDetector::has_pending_requests() { 43 assert(Service_lock->owned_by_self(), "Must own Service_lock"); 44 bool has_requests = false; 45 int num_memory_pools = MemoryService::num_memory_pools(); 46 for (int i = 0; i < num_memory_pools; i++) { 47 MemoryPool* pool = MemoryService::get_memory_pool(i); 48 SensorInfo* sensor = pool->usage_sensor(); 49 if (sensor != NULL) { 50 has_requests = has_requests || sensor->has_pending_requests(); 51 } 52 53 SensorInfo* gc_sensor = pool->gc_usage_sensor(); 54 if (gc_sensor != NULL) { 55 has_requests = has_requests || gc_sensor->has_pending_requests(); 56 } 57 } 58 return has_requests; 59 } 60 61 void LowMemoryDetector::process_sensor_changes(TRAPS) { 62 ResourceMark rm(THREAD); 63 HandleMark hm(THREAD); 64 65 // No need to hold Service_lock to call out to Java 66 int num_memory_pools = MemoryService::num_memory_pools(); 67 for (int i = 0; i < num_memory_pools; i++) { 68 MemoryPool* pool = MemoryService::get_memory_pool(i); 69 SensorInfo* sensor = pool->usage_sensor(); 70 SensorInfo* gc_sensor = pool->gc_usage_sensor(); 71 if (sensor != NULL && sensor->has_pending_requests()) { 72 sensor->process_pending_requests(CHECK); 73 } 74 if (gc_sensor != NULL && gc_sensor->has_pending_requests()) { 75 gc_sensor->process_pending_requests(CHECK); 76 } 77 } 78 } 79 80 // This method could be called from any Java threads 81 // and also VMThread. 82 void LowMemoryDetector::detect_low_memory() { 83 MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); 84 85 bool has_pending_requests = false; 86 int num_memory_pools = MemoryService::num_memory_pools(); 87 for (int i = 0; i < num_memory_pools; i++) { 88 MemoryPool* pool = MemoryService::get_memory_pool(i); 89 SensorInfo* sensor = pool->usage_sensor(); 90 if (sensor != NULL && 91 pool->usage_threshold()->is_high_threshold_supported() && 92 pool->usage_threshold()->high_threshold() != 0) { 93 MemoryUsage usage = pool->get_memory_usage(); 94 sensor->set_gauge_sensor_level(usage, 95 pool->usage_threshold()); 96 has_pending_requests = has_pending_requests || sensor->has_pending_requests(); 97 } 98 } 99 100 if (has_pending_requests) { 101 Service_lock->notify_all(); 102 } 103 } 104 105 // This method could be called from any Java threads 106 // and also VMThread. 107 void LowMemoryDetector::detect_low_memory(MemoryPool* pool) { 108 SensorInfo* sensor = pool->usage_sensor(); 109 if (sensor == NULL || 110 !pool->usage_threshold()->is_high_threshold_supported() || 111 pool->usage_threshold()->high_threshold() == 0) { 112 return; 113 } 114 115 { 116 MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); 117 118 MemoryUsage usage = pool->get_memory_usage(); 119 sensor->set_gauge_sensor_level(usage, 120 pool->usage_threshold()); 121 if (sensor->has_pending_requests()) { 122 // notify sensor state update 123 Service_lock->notify_all(); 124 } 125 } 126 } 127 128 // Only called by VMThread at GC time 129 void LowMemoryDetector::detect_after_gc_memory(MemoryPool* pool) { 130 SensorInfo* sensor = pool->gc_usage_sensor(); 131 if (sensor == NULL || 132 !pool->gc_usage_threshold()->is_high_threshold_supported() || 133 pool->gc_usage_threshold()->high_threshold() == 0) { 134 return; 135 } 136 137 { 138 MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); 139 140 MemoryUsage usage = pool->get_last_collection_usage(); 141 sensor->set_counter_sensor_level(usage, pool->gc_usage_threshold()); 142 143 if (sensor->has_pending_requests()) { 144 // notify sensor state update 145 Service_lock->notify_all(); 146 } 147 } 148 } 149 150 // recompute enabled flag 151 void LowMemoryDetector::recompute_enabled_for_collected_pools() { 152 bool enabled = false; 153 int num_memory_pools = MemoryService::num_memory_pools(); 154 for (int i=0; i<num_memory_pools; i++) { 155 MemoryPool* pool = MemoryService::get_memory_pool(i); 156 if (pool->is_collected_pool() && is_enabled(pool)) { 157 enabled = true; 158 break; 159 } 160 } 161 _enabled_for_collected_pools = enabled; 162 } 163 164 SensorInfo::SensorInfo() { 165 _sensor_obj = NULL; 166 _sensor_on = false; 167 _sensor_count = 0; 168 _pending_trigger_count = 0; 169 _pending_clear_count = 0; 170 } 171 172 // When this method is used, the memory usage is monitored 173 // as a gauge attribute. Sensor notifications (trigger or 174 // clear) is only emitted at the first time it crosses 175 // a threshold. 176 // 177 // High and low thresholds are designed to provide a 178 // hysteresis mechanism to avoid repeated triggering 179 // of notifications when the attribute value makes small oscillations 180 // around the high or low threshold value. 181 // 182 // The sensor will be triggered if: 183 // (1) the usage is crossing above the high threshold and 184 // the sensor is currently off and no pending 185 // trigger requests; or 186 // (2) the usage is crossing above the high threshold and 187 // the sensor will be off (i.e. sensor is currently on 188 // and has pending clear requests). 189 // 190 // Subsequent crossings of the high threshold value do not cause 191 // any triggers unless the usage becomes less than the low threshold. 192 // 193 // The sensor will be cleared if: 194 // (1) the usage is crossing below the low threshold and 195 // the sensor is currently on and no pending 196 // clear requests; or 197 // (2) the usage is crossing below the low threshold and 198 // the sensor will be on (i.e. sensor is currently off 199 // and has pending trigger requests). 200 // 201 // Subsequent crossings of the low threshold value do not cause 202 // any clears unless the usage becomes greater than or equal 203 // to the high threshold. 204 // 205 // If the current level is between high and low threshold, no change. 206 // 207 void SensorInfo::set_gauge_sensor_level(MemoryUsage usage, ThresholdSupport* high_low_threshold) { 208 assert(Service_lock->owned_by_self(), "Must own Service_lock"); 209 assert(high_low_threshold->is_high_threshold_supported(), "just checking"); 210 211 bool is_over_high = high_low_threshold->is_high_threshold_crossed(usage); 212 bool is_below_low = high_low_threshold->is_low_threshold_crossed(usage); 213 214 assert(!(is_over_high && is_below_low), "Can't be both true"); 215 216 if (is_over_high && 217 ((!_sensor_on && _pending_trigger_count == 0) || 218 _pending_clear_count > 0)) { 219 // low memory detected and need to increment the trigger pending count 220 // if the sensor is off or will be off due to _pending_clear_ > 0 221 // Request to trigger the sensor 222 _pending_trigger_count++; 223 _usage = usage; 224 225 if (_pending_clear_count > 0) { 226 // non-zero pending clear requests indicates that there are 227 // pending requests to clear this sensor. 228 // This trigger request needs to clear this clear count 229 // since the resulting sensor flag should be on. 230 _pending_clear_count = 0; 231 } 232 } else if (is_below_low && 233 ((_sensor_on && _pending_clear_count == 0) || 234 (_pending_trigger_count > 0 && _pending_clear_count == 0))) { 235 // memory usage returns below the threshold 236 // Request to clear the sensor if the sensor is on or will be on due to 237 // _pending_trigger_count > 0 and also no clear request 238 _pending_clear_count++; 239 } 240 } 241 242 // When this method is used, the memory usage is monitored as a 243 // simple counter attribute. The sensor will be triggered 244 // whenever the usage is crossing the threshold to keep track 245 // of the number of times the VM detects such a condition occurs. 246 // 247 // High and low thresholds are designed to provide a 248 // hysteresis mechanism to avoid repeated triggering 249 // of notifications when the attribute value makes small oscillations 250 // around the high or low threshold value. 251 // 252 // The sensor will be triggered if: 253 // - the usage is crossing above the high threshold regardless 254 // of the current sensor state. 255 // 256 // The sensor will be cleared if: 257 // (1) the usage is crossing below the low threshold and 258 // the sensor is currently on; or 259 // (2) the usage is crossing below the low threshold and 260 // the sensor will be on (i.e. sensor is currently off 261 // and has pending trigger requests). 262 void SensorInfo::set_counter_sensor_level(MemoryUsage usage, ThresholdSupport* counter_threshold) { 263 assert(Service_lock->owned_by_self(), "Must own Service_lock"); 264 assert(counter_threshold->is_high_threshold_supported(), "just checking"); 265 266 bool is_over_high = counter_threshold->is_high_threshold_crossed(usage); 267 bool is_below_low = counter_threshold->is_low_threshold_crossed(usage); 268 269 assert(!(is_over_high && is_below_low), "Can't be both true"); 270 271 if (is_over_high) { 272 _pending_trigger_count++; 273 _usage = usage; 274 _pending_clear_count = 0; 275 } else if (is_below_low && (_sensor_on || _pending_trigger_count > 0)) { 276 _pending_clear_count++; 277 } 278 } 279 280 void SensorInfo::oops_do(OopClosure* f) { 281 f->do_oop((oop*) &_sensor_obj); 282 } 283 284 void SensorInfo::process_pending_requests(TRAPS) { 285 int pending_count = pending_trigger_count(); 286 if (pending_clear_count() > 0) { 287 clear(pending_count, CHECK); 288 } else { 289 trigger(pending_count, CHECK); 290 } 291 292 } 293 294 void SensorInfo::trigger(int count, TRAPS) { 295 assert(count <= _pending_trigger_count, "just checking"); 296 if (_sensor_obj != NULL) { 297 InstanceKlass* sensorKlass = Management::sun_management_Sensor_klass(CHECK); 298 Handle sensor_h(THREAD, _sensor_obj); 299 300 Symbol* trigger_method_signature; 301 302 JavaValue result(T_VOID); 303 JavaCallArguments args(sensor_h); 304 args.push_int((int) count); 305 306 Handle usage_h = MemoryService::create_MemoryUsage_obj(_usage, THREAD); 307 // Call Sensor::trigger(int, MemoryUsage) to send notification to listeners. 308 // When OOME occurs and fails to allocate MemoryUsage object, call 309 // Sensor::trigger(int) instead. The pending request will be processed 310 // but no notification will be sent. 311 if (HAS_PENDING_EXCEPTION) { 312 assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOME here"); 313 CLEAR_PENDING_EXCEPTION; 314 trigger_method_signature = vmSymbols::int_void_signature(); 315 } else { 316 trigger_method_signature = vmSymbols::trigger_method_signature(); 317 args.push_oop(usage_h); 318 } 319 320 JavaCalls::call_virtual(&result, 321 sensorKlass, 322 vmSymbols::trigger_name(), 323 trigger_method_signature, 324 &args, 325 THREAD); 326 327 if (HAS_PENDING_EXCEPTION) { 328 // We just clear the OOM pending exception that we might have encountered 329 // in Java's tiggerAction(), and continue with updating the counters since 330 // the Java counters have been updated too. 331 assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOME here"); 332 CLEAR_PENDING_EXCEPTION; 333 } 334 } 335 336 { 337 // Holds Service_lock and update the sensor state 338 MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); 339 assert(_pending_trigger_count > 0, "Must have pending trigger"); 340 _sensor_on = true; 341 _sensor_count += count; 342 _pending_trigger_count = _pending_trigger_count - count; 343 } 344 } 345 346 void SensorInfo::clear(int count, TRAPS) { 347 { 348 // Holds Service_lock and update the sensor state 349 MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); 350 if (_pending_clear_count == 0) { 351 // Bail out if we lost a race to set_*_sensor_level() which may have 352 // reactivated the sensor in the meantime because it was triggered again. 353 return; 354 } 355 _sensor_on = false; 356 _sensor_count += count; 357 _pending_clear_count = 0; 358 _pending_trigger_count = _pending_trigger_count - count; 359 } 360 361 if (_sensor_obj != NULL) { 362 InstanceKlass* sensorKlass = Management::sun_management_Sensor_klass(CHECK); 363 Handle sensor(THREAD, _sensor_obj); 364 365 JavaValue result(T_VOID); 366 JavaCallArguments args(sensor); 367 args.push_int((int) count); 368 JavaCalls::call_virtual(&result, 369 sensorKlass, 370 vmSymbols::clear_name(), 371 vmSymbols::int_void_signature(), 372 &args, 373 CHECK); 374 } 375 } 376 377 //-------------------------------------------------------------- 378 // Non-product code 379 380 #ifndef PRODUCT 381 void SensorInfo::print() { 382 tty->print_cr("%s count = " SIZE_FORMAT " pending_triggers = %d pending_clears = %d", 383 (_sensor_on ? "on" : "off"), 384 _sensor_count, _pending_trigger_count, _pending_clear_count); 385 } 386 387 #endif // PRODUCT