1 /*
2 * Copyright (c) 2003, 2010, 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 *
41 // the threshold value is not allowed to be changed.
42 // If threshold == 0, no low memory detection is performed for
43 // that memory pool. The threshold can be set to any non-negative
44 // value.
45 //
46 // The default threshold of the Hotspot memory pools are:
47 // Eden space -1
48 // Survivor space 1 -1
49 // Survivor space 2 -1
50 // Old generation 0
51 // Perm generation 0
52 // CodeCache 0
53 //
54 // For heap memory, detection will be performed when GC finishes
55 // and also in the slow path allocation.
56 // For Code cache, detection will be performed in the allocation
57 // and deallocation.
58 //
59 // May need to deal with hysteresis effect.
60 //
61
62 class LowMemoryDetectorThread;
63 class OopClosure;
64 class MemoryPool;
65
66 class ThresholdSupport : public CHeapObj {
67 private:
68 bool _support_high_threshold;
69 bool _support_low_threshold;
70 size_t _high_threshold;
71 size_t _low_threshold;
72 public:
73 ThresholdSupport(bool support_high, bool support_low) {
74 _support_high_threshold = support_high;
75 _support_low_threshold = support_low;
76 _high_threshold = 0;
77 _low_threshold= 0;
78 }
79
80 size_t high_threshold() const { return _high_threshold; }
81 size_t low_threshold() const { return _low_threshold; }
82 bool is_high_threshold_supported() { return _support_high_threshold; }
194 //
195 // The sensor will be cleared if:
196 // (1) the usage is crossing below the low threshold and
197 // the sensor is currently on; or
198 // (2) the usage is crossing below the low threshold and
199 // the sensor will be on (i.e. sensor is currently off
200 // and has pending trigger requests).
201 //
202 void set_counter_sensor_level(MemoryUsage usage, ThresholdSupport* counter_threshold);
203
204 void process_pending_requests(TRAPS);
205 void oops_do(OopClosure* f);
206
207 #ifndef PRODUCT
208 // printing on default output stream;
209 void print();
210 #endif // PRODUCT
211 };
212
213 class LowMemoryDetector : public AllStatic {
214 friend class LowMemoryDetectorDisabler;
215 private:
216 // true if any collected heap has low memory detection enabled
217 static volatile bool _enabled_for_collected_pools;
218 // > 0 if temporary disabed
219 static volatile jint _disabled_count;
220
221 static LowMemoryDetectorThread* _detector_thread;
222 static void low_memory_detector_thread_entry(JavaThread* thread, TRAPS);
223 static void check_memory_usage();
224 static bool has_pending_requests();
225 static bool temporary_disabled() { return _disabled_count > 0; }
226 static void disable() { Atomic::inc(&_disabled_count); }
227 static void enable() { Atomic::dec(&_disabled_count); }
228
229 public:
230 static void initialize();
231 static void detect_low_memory();
232 static void detect_low_memory(MemoryPool* pool);
233 static void detect_after_gc_memory(MemoryPool* pool);
234
235 static bool is_enabled(MemoryPool* pool) {
236 // low memory detection is enabled for collected memory pools
237 // iff one of the collected memory pool has a sensor and the
238 // threshold set non-zero
239 if (pool->usage_sensor() == NULL) {
240 return false;
241 } else {
242 ThresholdSupport* threshold_support = pool->usage_threshold();
243 return (threshold_support->is_high_threshold_supported() ?
244 (threshold_support->high_threshold() > 0) : false);
245 }
246 }
247
248 // indicates if low memory detection is enabled for any collected
249 // memory pools
250 static inline bool is_enabled_for_collected_pools() {
258 static inline void detect_low_memory_for_collected_pools() {
259 // no-op if low memory detection not enabled
260 if (!is_enabled_for_collected_pools()) {
261 return;
262 }
263 int num_memory_pools = MemoryService::num_memory_pools();
264 for (int i=0; i<num_memory_pools; i++) {
265 MemoryPool* pool = MemoryService::get_memory_pool(i);
266
267 // if low memory detection is enabled then check if the
268 // current used exceeds the high threshold
269 if (pool->is_collected_pool() && is_enabled(pool)) {
270 size_t used = pool->used_in_bytes();
271 size_t high = pool->usage_threshold()->high_threshold();
272 if (used > high) {
273 detect_low_memory(pool);
274 }
275 }
276 }
277 }
278
279 };
280
281 class LowMemoryDetectorDisabler: public StackObj {
282 public:
283 LowMemoryDetectorDisabler()
284 {
285 LowMemoryDetector::disable();
286 }
287 ~LowMemoryDetectorDisabler()
288 {
289 assert(LowMemoryDetector::temporary_disabled(), "should be disabled!");
290 LowMemoryDetector::enable();
291 }
292 };
293
294 #endif // SHARE_VM_SERVICES_LOWMEMORYDETECTOR_HPP
|
1 /*
2 * Copyright (c) 2003, 2011, 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 *
41 // the threshold value is not allowed to be changed.
42 // If threshold == 0, no low memory detection is performed for
43 // that memory pool. The threshold can be set to any non-negative
44 // value.
45 //
46 // The default threshold of the Hotspot memory pools are:
47 // Eden space -1
48 // Survivor space 1 -1
49 // Survivor space 2 -1
50 // Old generation 0
51 // Perm generation 0
52 // CodeCache 0
53 //
54 // For heap memory, detection will be performed when GC finishes
55 // and also in the slow path allocation.
56 // For Code cache, detection will be performed in the allocation
57 // and deallocation.
58 //
59 // May need to deal with hysteresis effect.
60 //
61 // Memory detection code runs in the Service thread (serviceThread.hpp).
62
63 class OopClosure;
64 class MemoryPool;
65
66 class ThresholdSupport : public CHeapObj {
67 private:
68 bool _support_high_threshold;
69 bool _support_low_threshold;
70 size_t _high_threshold;
71 size_t _low_threshold;
72 public:
73 ThresholdSupport(bool support_high, bool support_low) {
74 _support_high_threshold = support_high;
75 _support_low_threshold = support_low;
76 _high_threshold = 0;
77 _low_threshold= 0;
78 }
79
80 size_t high_threshold() const { return _high_threshold; }
81 size_t low_threshold() const { return _low_threshold; }
82 bool is_high_threshold_supported() { return _support_high_threshold; }
194 //
195 // The sensor will be cleared if:
196 // (1) the usage is crossing below the low threshold and
197 // the sensor is currently on; or
198 // (2) the usage is crossing below the low threshold and
199 // the sensor will be on (i.e. sensor is currently off
200 // and has pending trigger requests).
201 //
202 void set_counter_sensor_level(MemoryUsage usage, ThresholdSupport* counter_threshold);
203
204 void process_pending_requests(TRAPS);
205 void oops_do(OopClosure* f);
206
207 #ifndef PRODUCT
208 // printing on default output stream;
209 void print();
210 #endif // PRODUCT
211 };
212
213 class LowMemoryDetector : public AllStatic {
214 friend class LowMemoryDetectorDisabler;
215 friend class ServiceThread;
216 private:
217 // true if any collected heap has low memory detection enabled
218 static volatile bool _enabled_for_collected_pools;
219 // > 0 if temporary disabed
220 static volatile jint _disabled_count;
221
222 static void check_memory_usage();
223 static bool has_pending_requests();
224 static bool temporary_disabled() { return _disabled_count > 0; }
225 static void disable() { Atomic::inc(&_disabled_count); }
226 static void enable() { Atomic::dec(&_disabled_count); }
227 static void process_sensor_changes(TRAPS);
228
229 public:
230 static void detect_low_memory();
231 static void detect_low_memory(MemoryPool* pool);
232 static void detect_after_gc_memory(MemoryPool* pool);
233
234 static bool is_enabled(MemoryPool* pool) {
235 // low memory detection is enabled for collected memory pools
236 // iff one of the collected memory pool has a sensor and the
237 // threshold set non-zero
238 if (pool->usage_sensor() == NULL) {
239 return false;
240 } else {
241 ThresholdSupport* threshold_support = pool->usage_threshold();
242 return (threshold_support->is_high_threshold_supported() ?
243 (threshold_support->high_threshold() > 0) : false);
244 }
245 }
246
247 // indicates if low memory detection is enabled for any collected
248 // memory pools
249 static inline bool is_enabled_for_collected_pools() {
257 static inline void detect_low_memory_for_collected_pools() {
258 // no-op if low memory detection not enabled
259 if (!is_enabled_for_collected_pools()) {
260 return;
261 }
262 int num_memory_pools = MemoryService::num_memory_pools();
263 for (int i=0; i<num_memory_pools; i++) {
264 MemoryPool* pool = MemoryService::get_memory_pool(i);
265
266 // if low memory detection is enabled then check if the
267 // current used exceeds the high threshold
268 if (pool->is_collected_pool() && is_enabled(pool)) {
269 size_t used = pool->used_in_bytes();
270 size_t high = pool->usage_threshold()->high_threshold();
271 if (used > high) {
272 detect_low_memory(pool);
273 }
274 }
275 }
276 }
277 };
278
279 class LowMemoryDetectorDisabler: public StackObj {
280 public:
281 LowMemoryDetectorDisabler()
282 {
283 LowMemoryDetector::disable();
284 }
285 ~LowMemoryDetectorDisabler()
286 {
287 assert(LowMemoryDetector::temporary_disabled(), "should be disabled!");
288 LowMemoryDetector::enable();
289 }
290 };
291
292 #endif // SHARE_VM_SERVICES_LOWMEMORYDETECTOR_HPP
|