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  */
  24 
  25 #ifndef SHARE_VM_SERVICES_MEMORYPOOL_HPP
  26 #define SHARE_VM_SERVICES_MEMORYPOOL_HPP
  27 
  28 #include "gc_implementation/shared/mutableSpace.hpp"
  29 #include "memory/defNewGeneration.hpp"
  30 #include "memory/heap.hpp"
  31 #include "memory/space.hpp"
  32 #include "services/memoryUsage.hpp"
  33 #include "utilities/macros.hpp"
  34 #if INCLUDE_ALL_GCS
  35 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
  36 #endif // INCLUDE_ALL_GCS
  37 
  38 // A memory pool represents the memory area that the VM manages.
  39 // The Java virtual machine has at least one memory pool
  40 // and it may create or remove memory pools during execution.
  41 // A memory pool can belong to the heap or the non-heap memory.
  42 // A Java virtual machine may also have memory pools belonging to
  43 // both heap and non-heap memory.
  44 
  45 // Forward declaration
  46 class MemoryManager;
  47 class SensorInfo;
  48 class Generation;
  49 class DefNewGeneration;
  50 class ThresholdSupport;
  51 
  52 class MemoryPool : public CHeapObj<mtInternal> {
  53   friend class MemoryManager;
  54  public:
  55   enum PoolType {
  56     Heap    = 1,
  57     NonHeap = 2
  58   };
  59 
  60  private:
  61   enum {
  62     max_num_managers = 5
  63   };
  64 
  65   // We could make some of the following as performance counters
  66   // for external monitoring.
  67   const char*      _name;
  68   PoolType         _type;
  69   size_t           _initial_size;
  70   size_t           _max_size;
  71   bool             _available_for_allocation; // Default is true
  72   MemoryManager*   _managers[max_num_managers];
  73   int              _num_managers;
  74   MemoryUsage      _peak_usage;               // Peak memory usage
  75   MemoryUsage      _after_gc_usage;           // After GC memory usage
  76 
  77   ThresholdSupport* _usage_threshold;
  78   ThresholdSupport* _gc_usage_threshold;
  79 
  80   SensorInfo*      _usage_sensor;
  81   SensorInfo*      _gc_usage_sensor;
  82 
  83   volatile instanceOop _memory_pool_obj;
  84 
  85   void add_manager(MemoryManager* mgr);
  86 
  87  protected:
  88   static const size_t _undefined_size = (size_t) -1;
  89 
  90  public:
  91   MemoryPool(const char* name,
  92              PoolType type,
  93              size_t init_size,
  94              size_t max_size,
  95              bool support_usage_threshold,
  96              bool support_gc_threshold);
  97 
  98   const char* name()                       { return _name; }
  99   bool        is_heap()                    { return _type == Heap; }
 100   bool        is_non_heap()                { return _type == NonHeap; }
 101   size_t      initial_size()   const       { return _initial_size; }
 102   int         num_memory_managers() const  { return _num_managers; }
 103   // max size could be changed
 104   virtual size_t max_size()    const       { return _max_size; }
 105 
 106   bool is_pool(instanceHandle pool) { return (pool() == _memory_pool_obj); }
 107 
 108   bool available_for_allocation()   { return _available_for_allocation; }
 109   bool set_available_for_allocation(bool value) {
 110     bool prev = _available_for_allocation;
 111     _available_for_allocation = value;
 112     return prev;
 113   }
 114 
 115   MemoryManager* get_memory_manager(int index) {
 116     assert(index >= 0 && index < _num_managers, "Invalid index");
 117     return _managers[index];
 118   }
 119 
 120   // Records current memory usage if it's a peak usage
 121   void record_peak_memory_usage();
 122 
 123   MemoryUsage get_peak_memory_usage() {
 124     // check current memory usage first and then return peak usage
 125     record_peak_memory_usage();
 126     return _peak_usage;
 127   }
 128   void        reset_peak_memory_usage() {
 129     _peak_usage = get_memory_usage();
 130   }
 131 
 132   ThresholdSupport* usage_threshold()      { return _usage_threshold; }
 133   ThresholdSupport* gc_usage_threshold()   { return _gc_usage_threshold; }
 134 
 135   SensorInfo*       usage_sensor()         {  return _usage_sensor; }
 136   SensorInfo*       gc_usage_sensor()      { return _gc_usage_sensor; }
 137 
 138   void        set_usage_sensor_obj(instanceHandle s);
 139   void        set_gc_usage_sensor_obj(instanceHandle s);
 140   void        set_last_collection_usage(MemoryUsage u)  { _after_gc_usage = u; }
 141 
 142   virtual instanceOop get_memory_pool_instance(TRAPS);
 143   virtual MemoryUsage get_memory_usage() = 0;
 144   virtual size_t      used_in_bytes() = 0;
 145   virtual bool        is_collected_pool()         { return false; }
 146   virtual MemoryUsage get_last_collection_usage() { return _after_gc_usage; }
 147 
 148   // GC support
 149   void oops_do(OopClosure* f);
 150 };
 151 
 152 class CollectedMemoryPool : public MemoryPool {
 153 public:
 154   CollectedMemoryPool(const char* name, PoolType type, size_t init_size, size_t max_size, bool support_usage_threshold) :
 155     MemoryPool(name, type, init_size, max_size, support_usage_threshold, true) {};
 156   bool is_collected_pool()            { return true; }
 157 };
 158 
 159 class ContiguousSpacePool : public CollectedMemoryPool {
 160 private:
 161   ContiguousSpace* _space;
 162 
 163 public:
 164   ContiguousSpacePool(ContiguousSpace* space, const char* name, PoolType type, size_t max_size, bool support_usage_threshold);
 165 
 166   ContiguousSpace* space()              { return _space; }
 167   MemoryUsage get_memory_usage();
 168   size_t used_in_bytes()                { return space()->used(); }
 169 };
 170 
 171 class SurvivorContiguousSpacePool : public CollectedMemoryPool {
 172 private:
 173   DefNewGeneration* _gen;
 174 
 175 public:
 176   SurvivorContiguousSpacePool(DefNewGeneration* gen,
 177                               const char* name,
 178                               PoolType type,
 179                               size_t max_size,
 180                               bool support_usage_threshold);
 181 
 182   MemoryUsage get_memory_usage();
 183 
 184   size_t used_in_bytes() {
 185     return _gen->from()->used();
 186   }
 187   size_t committed_in_bytes() {
 188     return _gen->from()->capacity();
 189   }
 190 };
 191 
 192 #if INCLUDE_ALL_GCS
 193 class CompactibleFreeListSpacePool : public CollectedMemoryPool {
 194 private:
 195   CompactibleFreeListSpace* _space;
 196 public:
 197   CompactibleFreeListSpacePool(CompactibleFreeListSpace* space,
 198                                const char* name,
 199                                PoolType type,
 200                                size_t max_size,
 201                                bool support_usage_threshold);
 202 
 203   MemoryUsage get_memory_usage();
 204   size_t used_in_bytes()            { return _space->used(); }
 205 };
 206 #endif // INCLUDE_ALL_GCS
 207 
 208 
 209 class GenerationPool : public CollectedMemoryPool {
 210 private:
 211   Generation* _gen;
 212 public:
 213   GenerationPool(Generation* gen, const char* name, PoolType type, bool support_usage_threshold);
 214 
 215   MemoryUsage get_memory_usage();
 216   size_t used_in_bytes()                { return _gen->used(); }
 217 };
 218 
 219 class CodeHeapPool: public MemoryPool {
 220 private:
 221   CodeHeap* _codeHeap;
 222 public:
 223   CodeHeapPool(CodeHeap* codeHeap, const char* name, bool support_usage_threshold);
 224   MemoryUsage get_memory_usage();
 225   size_t used_in_bytes()            { return _codeHeap->allocated_capacity(); }
 226 };
 227 
 228 class MetaspacePool : public MemoryPool {
 229   size_t calculate_max_size() const;
 230   size_t capacity_in_bytes() const;
 231  public:
 232   MetaspacePool();
 233   MemoryUsage get_memory_usage();
 234   size_t used_in_bytes();
 235 };
 236 
 237 class CompressedKlassSpacePool : public MemoryPool {
 238   size_t capacity_in_bytes() const;
 239  public:
 240   CompressedKlassSpacePool();
 241   MemoryUsage get_memory_usage();
 242   size_t used_in_bytes();
 243 };
 244 
 245 class EmptyCompressedKlassSpacePool : public MemoryPool {
 246  public:
 247   EmptyCompressedKlassSpacePool() :
 248     MemoryPool("Compressed Klass Space", NonHeap, _undefined_size, _undefined_size, true, false) {}
 249   MemoryUsage get_memory_usage() { return MemoryUsage(_undefined_size, 0, 0, _undefined_size); }
 250   size_t used_in_bytes() { return 0; }
 251 };
 252 
 253 #endif // SHARE_VM_SERVICES_MEMORYPOOL_HPP