src/share/vm/services/lowMemoryDetector.hpp

Mon, 12 Nov 2012 16:15:05 -0500

author
hseigel
date
Mon, 12 Nov 2012 16:15:05 -0500
changeset 4278
070d523b96a7
parent 4153
b9a9ed0f8eeb
child 6876
710a3c8b516e
permissions
-rw-r--r--

8001471: Klass::cast() does nothing
Summary: Remove function Klass::cast() and calls to it.
Reviewed-by: dholmes, coleenp

     1 /*
     2  * Copyright (c) 2003, 2012, 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  */
    25 #ifndef SHARE_VM_SERVICES_LOWMEMORYDETECTOR_HPP
    26 #define SHARE_VM_SERVICES_LOWMEMORYDETECTOR_HPP
    28 #include "memory/allocation.hpp"
    29 #include "services/memoryPool.hpp"
    30 #include "services/memoryService.hpp"
    32 // Low Memory Detection Support
    33 // Two memory alarms in the JDK (we called them sensors).
    34 //   - Heap memory sensor
    35 //   - Non-heap memory sensor
    36 // When the VM detects if the memory usage of a memory pool has reached
    37 // or exceeded its threshold, it will trigger the sensor for the type
    38 // of the memory pool (heap or nonheap or both).
    39 //
    40 // If threshold == -1, no low memory detection is supported and
    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).
    63 class OopClosure;
    64 class MemoryPool;
    66 class ThresholdSupport : public CHeapObj<mtInternal> {
    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   }
    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; }
    83   bool        is_low_threshold_supported()  { return _support_low_threshold; }
    85   bool        is_high_threshold_crossed(MemoryUsage usage) {
    86     if (_support_high_threshold && _high_threshold > 0) {
    87       return (usage.used() >= _high_threshold);
    88     }
    89     return false;
    90   }
    91   bool        is_low_threshold_crossed(MemoryUsage usage) {
    92     if (_support_low_threshold && _low_threshold > 0) {
    93       return (usage.used() < _low_threshold);
    94     }
    95     return false;
    96   }
    98   size_t      set_high_threshold(size_t new_threshold) {
    99     assert(_support_high_threshold, "can only be set if supported");
   100     assert(new_threshold >= _low_threshold, "new_threshold must be >= _low_threshold");
   101     size_t prev = _high_threshold;
   102     _high_threshold = new_threshold;
   103     return prev;
   104   }
   106   size_t      set_low_threshold(size_t new_threshold) {
   107     assert(_support_low_threshold, "can only be set if supported");
   108     assert(new_threshold <= _high_threshold, "new_threshold must be <= _high_threshold");
   109     size_t prev = _low_threshold;
   110     _low_threshold = new_threshold;
   111     return prev;
   112   }
   113 };
   115 class SensorInfo : public CHeapObj<mtInternal> {
   116 private:
   117   instanceOop     _sensor_obj;
   118   bool            _sensor_on;
   119   size_t          _sensor_count;
   121   // before the actual sensor on flag and sensor count are set
   122   // we maintain the number of pending triggers and clears.
   123   // _pending_trigger_count means the number of pending triggers
   124   // and the sensor count should be incremented by the same number.
   126   int             _pending_trigger_count;
   128   // _pending_clear_count takes precedence if it's > 0 which
   129   // indicates the resulting sensor will be off
   130   // Sensor trigger requests will reset this clear count to
   131   // indicate the resulting flag should be on.
   133   int             _pending_clear_count;
   135   MemoryUsage     _usage;
   137   void clear(int count, TRAPS);
   138   void trigger(int count, TRAPS);
   139 public:
   140   SensorInfo();
   141   void set_sensor(instanceOop sensor) {
   142     assert(_sensor_obj == NULL, "Should be set only once");
   143     _sensor_obj = sensor;
   144   }
   146   bool has_pending_requests() {
   147     return (_pending_trigger_count > 0 || _pending_clear_count > 0);
   148   }
   150   int pending_trigger_count()      { return _pending_trigger_count; }
   151   int pending_clear_count()        { return _pending_clear_count; }
   153   // When this method is used, the memory usage is monitored
   154   // as a gauge attribute.  High and low thresholds are designed
   155   // to provide a hysteresis mechanism to avoid repeated triggering
   156   // of notifications when the attribute value makes small oscillations
   157   // around the high or low threshold value.
   158   //
   159   // The sensor will be triggered if:
   160   //  (1) the usage is crossing above the high threshold and
   161   //      the sensor is currently off and no pending
   162   //      trigger requests; or
   163   //  (2) the usage is crossing above the high threshold and
   164   //      the sensor will be off (i.e. sensor is currently on
   165   //      and has pending clear requests).
   166   //
   167   // Subsequent crossings of the high threshold value do not cause
   168   // any triggers unless the usage becomes less than the low threshold.
   169   //
   170   // The sensor will be cleared if:
   171   //  (1) the usage is crossing below the low threshold and
   172   //      the sensor is currently on and no pending
   173   //      clear requests; or
   174   //  (2) the usage is crossing below the low threshold and
   175   //      the sensor will be on (i.e. sensor is currently off
   176   //      and has pending trigger requests).
   177   //
   178   // Subsequent crossings of the low threshold value do not cause
   179   // any clears unless the usage becomes greater than or equal
   180   // to the high threshold.
   181   //
   182   // If the current level is between high and low threhsold, no change.
   183   //
   184   void set_gauge_sensor_level(MemoryUsage usage, ThresholdSupport* high_low_threshold);
   186   // When this method is used, the memory usage is monitored as a
   187   // simple counter attribute.  The sensor will be triggered
   188   // whenever the usage is crossing the threshold to keep track
   189   // of the number of times the VM detects such a condition occurs.
   190   //
   191   // The sensor will be triggered if:
   192   //   - the usage is crossing above the high threshold regardless
   193   //     of the current sensor state.
   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);
   204   void process_pending_requests(TRAPS);
   205   void oops_do(OopClosure* f);
   207 #ifndef PRODUCT
   208   // printing on default output stream;
   209   void print();
   210 #endif // PRODUCT
   211 };
   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;
   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);
   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);
   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   }
   247   // indicates if low memory detection is enabled for any collected
   248   // memory pools
   249   static inline bool is_enabled_for_collected_pools() {
   250     return !temporary_disabled() && _enabled_for_collected_pools;
   251   }
   253   // recompute enabled flag
   254   static void recompute_enabled_for_collected_pools();
   256   // low memory detection for collected memory 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);
   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 };
   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 };
   292 #endif // SHARE_VM_SERVICES_LOWMEMORYDETECTOR_HPP

mercurial