memoryManager.hpp revision 3465:d2a62e0f25eb
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 *
23 */
24
25#ifndef SHARE_VM_SERVICES_MEMORYMANAGER_HPP
26#define SHARE_VM_SERVICES_MEMORYMANAGER_HPP
27
28#include "memory/allocation.hpp"
29#include "runtime/timer.hpp"
30#include "services/memoryUsage.hpp"
31
32// A memory manager is responsible for managing one or more memory pools.
33// The garbage collector is one type of memory managers responsible
34// for reclaiming memory occupied by unreachable objects.  A Java virtual
35// machine may have one or more memory managers.   It may
36// add or remove memory managers during execution.
37// A memory pool can be managed by more than one memory managers.
38
39class MemoryPool;
40class GCMemoryManager;
41class OopClosure;
42
43class MemoryManager : public CHeapObj<mtInternal> {
44private:
45  enum {
46    max_num_pools = 10
47  };
48
49  MemoryPool* _pools[max_num_pools];
50  int         _num_pools;
51
52protected:
53  volatile instanceOop _memory_mgr_obj;
54
55public:
56  enum Name {
57    Abstract,
58    CodeCache,
59    Copy,
60    MarkSweepCompact,
61    ParNew,
62    ConcurrentMarkSweep,
63    PSScavenge,
64    PSMarkSweep,
65    G1YoungGen,
66    G1OldGen
67  };
68
69  MemoryManager();
70
71  int num_memory_pools() const           { return _num_pools; }
72  MemoryPool* get_memory_pool(int index) {
73    assert(index >= 0 && index < _num_pools, "Invalid index");
74    return _pools[index];
75  }
76
77  void add_pool(MemoryPool* pool);
78
79  bool is_manager(instanceHandle mh)     { return mh() == _memory_mgr_obj; }
80
81  virtual instanceOop get_memory_manager_instance(TRAPS);
82  virtual MemoryManager::Name kind()     { return MemoryManager::Abstract; }
83  virtual bool is_gc_memory_manager()    { return false; }
84  virtual const char* name() = 0;
85
86  // GC support
87  void oops_do(OopClosure* f);
88
89  // Static factory methods to get a memory manager of a specific type
90  static MemoryManager*   get_code_cache_memory_manager();
91  static GCMemoryManager* get_copy_memory_manager();
92  static GCMemoryManager* get_msc_memory_manager();
93  static GCMemoryManager* get_parnew_memory_manager();
94  static GCMemoryManager* get_cms_memory_manager();
95  static GCMemoryManager* get_psScavenge_memory_manager();
96  static GCMemoryManager* get_psMarkSweep_memory_manager();
97  static GCMemoryManager* get_g1YoungGen_memory_manager();
98  static GCMemoryManager* get_g1OldGen_memory_manager();
99
100};
101
102class CodeCacheMemoryManager : public MemoryManager {
103private:
104public:
105  CodeCacheMemoryManager() : MemoryManager() {}
106
107  MemoryManager::Name kind() { return MemoryManager::CodeCache; }
108  const char* name()         { return "CodeCacheManager"; }
109};
110
111class GCStatInfo : public ResourceObj {
112private:
113  size_t _index;
114  jlong  _start_time;
115  jlong  _end_time;
116
117  // We keep memory usage of all memory pools
118  MemoryUsage* _before_gc_usage_array;
119  MemoryUsage* _after_gc_usage_array;
120  int          _usage_array_size;
121
122  void set_gc_usage(int pool_index, MemoryUsage, bool before_gc);
123
124public:
125  GCStatInfo(int num_pools);
126  ~GCStatInfo();
127
128  size_t gc_index()               { return _index; }
129  jlong  start_time()             { return _start_time; }
130  jlong  end_time()               { return _end_time; }
131  int    usage_array_size()       { return _usage_array_size; }
132  MemoryUsage before_gc_usage_for_pool(int pool_index) {
133    assert(pool_index >= 0 && pool_index < _usage_array_size, "Range checking");
134    return _before_gc_usage_array[pool_index];
135  }
136  MemoryUsage after_gc_usage_for_pool(int pool_index) {
137    assert(pool_index >= 0 && pool_index < _usage_array_size, "Range checking");
138    return _after_gc_usage_array[pool_index];
139  }
140
141  MemoryUsage* before_gc_usage_array() { return _before_gc_usage_array; }
142  MemoryUsage* after_gc_usage_array()  { return _after_gc_usage_array; }
143
144  void set_index(size_t index)    { _index = index; }
145  void set_start_time(jlong time) { _start_time = time; }
146  void set_end_time(jlong time)   { _end_time = time; }
147  void set_before_gc_usage(int pool_index, MemoryUsage usage) {
148    assert(pool_index >= 0 && pool_index < _usage_array_size, "Range checking");
149    set_gc_usage(pool_index, usage, true /* before gc */);
150  }
151  void set_after_gc_usage(int pool_index, MemoryUsage usage) {
152    assert(pool_index >= 0 && pool_index < _usage_array_size, "Range checking");
153    set_gc_usage(pool_index, usage, false /* after gc */);
154  }
155
156  void clear();
157};
158
159class GCMemoryManager : public MemoryManager {
160private:
161  // TODO: We should unify the GCCounter and GCMemoryManager statistic
162  size_t       _num_collections;
163  elapsedTimer _accumulated_timer;
164  elapsedTimer _gc_timer;         // for measuring every GC duration
165  GCStatInfo*  _last_gc_stat;
166  Mutex*       _last_gc_lock;
167  GCStatInfo*  _current_gc_stat;
168  int          _num_gc_threads;
169  volatile bool _notification_enabled;
170public:
171  GCMemoryManager();
172  ~GCMemoryManager();
173
174  void   initialize_gc_stat_info();
175
176  bool   is_gc_memory_manager()         { return true; }
177  jlong  gc_time_ms()                   { return _accumulated_timer.milliseconds(); }
178  size_t gc_count()                     { return _num_collections; }
179  int    num_gc_threads()               { return _num_gc_threads; }
180  void   set_num_gc_threads(int count)  { _num_gc_threads = count; }
181
182  void   gc_begin(bool recordGCBeginTime, bool recordPreGCUsage,
183                  bool recordAccumulatedGCTime);
184  void   gc_end(bool recordPostGCUsage, bool recordAccumulatedGCTime,
185                bool recordGCEndTime, bool countCollection, GCCause::Cause cause);
186
187  void        reset_gc_stat()   { _num_collections = 0; _accumulated_timer.reset(); }
188
189  // Copy out _last_gc_stat to the given destination, returning
190  // the collection count. Zero signifies no gc has taken place.
191  size_t get_last_gc_stat(GCStatInfo* dest);
192
193  void set_notification_enabled(bool enabled) { _notification_enabled = enabled; }
194  bool is_notification_enabled() { return _notification_enabled; }
195  virtual MemoryManager::Name kind() = 0;
196};
197
198// These subclasses of GCMemoryManager are defined to include
199// GC-specific information.
200// TODO: Add GC-specific information
201class CopyMemoryManager : public GCMemoryManager {
202private:
203public:
204  CopyMemoryManager() : GCMemoryManager() {}
205
206  MemoryManager::Name kind() { return MemoryManager::Copy; }
207  const char* name()         { return "Copy"; }
208};
209
210class MSCMemoryManager : public GCMemoryManager {
211private:
212public:
213  MSCMemoryManager() : GCMemoryManager() {}
214
215  MemoryManager::Name kind() { return MemoryManager::MarkSweepCompact; }
216  const char* name()         { return "MarkSweepCompact"; }
217
218};
219
220class ParNewMemoryManager : public GCMemoryManager {
221private:
222public:
223  ParNewMemoryManager() : GCMemoryManager() {}
224
225  MemoryManager::Name kind() { return MemoryManager::ParNew; }
226  const char* name()         { return "ParNew"; }
227
228};
229
230class CMSMemoryManager : public GCMemoryManager {
231private:
232public:
233  CMSMemoryManager() : GCMemoryManager() {}
234
235  MemoryManager::Name kind() { return MemoryManager::ConcurrentMarkSweep; }
236  const char* name()         { return "ConcurrentMarkSweep";}
237
238};
239
240class PSScavengeMemoryManager : public GCMemoryManager {
241private:
242public:
243  PSScavengeMemoryManager() : GCMemoryManager() {}
244
245  MemoryManager::Name kind() { return MemoryManager::PSScavenge; }
246  const char* name()         { return "PS Scavenge"; }
247
248};
249
250class PSMarkSweepMemoryManager : public GCMemoryManager {
251private:
252public:
253  PSMarkSweepMemoryManager() : GCMemoryManager() {}
254
255  MemoryManager::Name kind() { return MemoryManager::PSMarkSweep; }
256  const char* name()         { return "PS MarkSweep"; }
257};
258
259class G1YoungGenMemoryManager : public GCMemoryManager {
260private:
261public:
262  G1YoungGenMemoryManager() : GCMemoryManager() {}
263
264  MemoryManager::Name kind() { return MemoryManager::G1YoungGen; }
265  const char* name()         { return "G1 Young Generation"; }
266};
267
268class G1OldGenMemoryManager : public GCMemoryManager {
269private:
270public:
271  G1OldGenMemoryManager() : GCMemoryManager() {}
272
273  MemoryManager::Name kind() { return MemoryManager::G1OldGen; }
274  const char* name()         { return "G1 Old Generation"; }
275};
276
277#endif // SHARE_VM_SERVICES_MEMORYMANAGER_HPP
278