1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/services/memoryManager.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,287 @@ 1.4 +/* 1.5 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_SERVICES_MEMORYMANAGER_HPP 1.29 +#define SHARE_VM_SERVICES_MEMORYMANAGER_HPP 1.30 + 1.31 +#include "memory/allocation.hpp" 1.32 +#include "runtime/timer.hpp" 1.33 +#include "services/memoryUsage.hpp" 1.34 + 1.35 +// A memory manager is responsible for managing one or more memory pools. 1.36 +// The garbage collector is one type of memory managers responsible 1.37 +// for reclaiming memory occupied by unreachable objects. A Java virtual 1.38 +// machine may have one or more memory managers. It may 1.39 +// add or remove memory managers during execution. 1.40 +// A memory pool can be managed by more than one memory managers. 1.41 + 1.42 +class MemoryPool; 1.43 +class GCMemoryManager; 1.44 +class OopClosure; 1.45 + 1.46 +class MemoryManager : public CHeapObj<mtInternal> { 1.47 +private: 1.48 + enum { 1.49 + max_num_pools = 10 1.50 + }; 1.51 + 1.52 + MemoryPool* _pools[max_num_pools]; 1.53 + int _num_pools; 1.54 + 1.55 +protected: 1.56 + volatile instanceOop _memory_mgr_obj; 1.57 + 1.58 +public: 1.59 + enum Name { 1.60 + Abstract, 1.61 + CodeCache, 1.62 + Metaspace, 1.63 + Copy, 1.64 + MarkSweepCompact, 1.65 + ParNew, 1.66 + ConcurrentMarkSweep, 1.67 + PSScavenge, 1.68 + PSMarkSweep, 1.69 + G1YoungGen, 1.70 + G1OldGen 1.71 + }; 1.72 + 1.73 + MemoryManager(); 1.74 + 1.75 + int num_memory_pools() const { return _num_pools; } 1.76 + MemoryPool* get_memory_pool(int index) { 1.77 + assert(index >= 0 && index < _num_pools, "Invalid index"); 1.78 + return _pools[index]; 1.79 + } 1.80 + 1.81 + void add_pool(MemoryPool* pool); 1.82 + 1.83 + bool is_manager(instanceHandle mh) { return mh() == _memory_mgr_obj; } 1.84 + 1.85 + virtual instanceOop get_memory_manager_instance(TRAPS); 1.86 + virtual MemoryManager::Name kind() { return MemoryManager::Abstract; } 1.87 + virtual bool is_gc_memory_manager() { return false; } 1.88 + virtual const char* name() = 0; 1.89 + 1.90 + // GC support 1.91 + void oops_do(OopClosure* f); 1.92 + 1.93 + // Static factory methods to get a memory manager of a specific type 1.94 + static MemoryManager* get_code_cache_memory_manager(); 1.95 + static MemoryManager* get_metaspace_memory_manager(); 1.96 + static GCMemoryManager* get_copy_memory_manager(); 1.97 + static GCMemoryManager* get_msc_memory_manager(); 1.98 + static GCMemoryManager* get_parnew_memory_manager(); 1.99 + static GCMemoryManager* get_cms_memory_manager(); 1.100 + static GCMemoryManager* get_psScavenge_memory_manager(); 1.101 + static GCMemoryManager* get_psMarkSweep_memory_manager(); 1.102 + static GCMemoryManager* get_g1YoungGen_memory_manager(); 1.103 + static GCMemoryManager* get_g1OldGen_memory_manager(); 1.104 + 1.105 +}; 1.106 + 1.107 +class CodeCacheMemoryManager : public MemoryManager { 1.108 +private: 1.109 +public: 1.110 + CodeCacheMemoryManager() : MemoryManager() {} 1.111 + 1.112 + MemoryManager::Name kind() { return MemoryManager::CodeCache; } 1.113 + const char* name() { return "CodeCacheManager"; } 1.114 +}; 1.115 + 1.116 +class MetaspaceMemoryManager : public MemoryManager { 1.117 +public: 1.118 + MetaspaceMemoryManager() : MemoryManager() {} 1.119 + 1.120 + MemoryManager::Name kind() { return MemoryManager::Metaspace; } 1.121 + const char *name() { return "Metaspace Manager"; } 1.122 +}; 1.123 + 1.124 +class GCStatInfo : public ResourceObj { 1.125 +private: 1.126 + size_t _index; 1.127 + jlong _start_time; 1.128 + jlong _end_time; 1.129 + 1.130 + // We keep memory usage of all memory pools 1.131 + MemoryUsage* _before_gc_usage_array; 1.132 + MemoryUsage* _after_gc_usage_array; 1.133 + int _usage_array_size; 1.134 + 1.135 + void set_gc_usage(int pool_index, MemoryUsage, bool before_gc); 1.136 + 1.137 +public: 1.138 + GCStatInfo(int num_pools); 1.139 + ~GCStatInfo(); 1.140 + 1.141 + size_t gc_index() { return _index; } 1.142 + jlong start_time() { return _start_time; } 1.143 + jlong end_time() { return _end_time; } 1.144 + int usage_array_size() { return _usage_array_size; } 1.145 + MemoryUsage before_gc_usage_for_pool(int pool_index) { 1.146 + assert(pool_index >= 0 && pool_index < _usage_array_size, "Range checking"); 1.147 + return _before_gc_usage_array[pool_index]; 1.148 + } 1.149 + MemoryUsage after_gc_usage_for_pool(int pool_index) { 1.150 + assert(pool_index >= 0 && pool_index < _usage_array_size, "Range checking"); 1.151 + return _after_gc_usage_array[pool_index]; 1.152 + } 1.153 + 1.154 + MemoryUsage* before_gc_usage_array() { return _before_gc_usage_array; } 1.155 + MemoryUsage* after_gc_usage_array() { return _after_gc_usage_array; } 1.156 + 1.157 + void set_index(size_t index) { _index = index; } 1.158 + void set_start_time(jlong time) { _start_time = time; } 1.159 + void set_end_time(jlong time) { _end_time = time; } 1.160 + void set_before_gc_usage(int pool_index, MemoryUsage usage) { 1.161 + assert(pool_index >= 0 && pool_index < _usage_array_size, "Range checking"); 1.162 + set_gc_usage(pool_index, usage, true /* before gc */); 1.163 + } 1.164 + void set_after_gc_usage(int pool_index, MemoryUsage usage) { 1.165 + assert(pool_index >= 0 && pool_index < _usage_array_size, "Range checking"); 1.166 + set_gc_usage(pool_index, usage, false /* after gc */); 1.167 + } 1.168 + 1.169 + void clear(); 1.170 +}; 1.171 + 1.172 +class GCMemoryManager : public MemoryManager { 1.173 +private: 1.174 + // TODO: We should unify the GCCounter and GCMemoryManager statistic 1.175 + size_t _num_collections; 1.176 + elapsedTimer _accumulated_timer; 1.177 + elapsedTimer _gc_timer; // for measuring every GC duration 1.178 + GCStatInfo* _last_gc_stat; 1.179 + Mutex* _last_gc_lock; 1.180 + GCStatInfo* _current_gc_stat; 1.181 + int _num_gc_threads; 1.182 + volatile bool _notification_enabled; 1.183 +public: 1.184 + GCMemoryManager(); 1.185 + ~GCMemoryManager(); 1.186 + 1.187 + void initialize_gc_stat_info(); 1.188 + 1.189 + bool is_gc_memory_manager() { return true; } 1.190 + jlong gc_time_ms() { return _accumulated_timer.milliseconds(); } 1.191 + size_t gc_count() { return _num_collections; } 1.192 + int num_gc_threads() { return _num_gc_threads; } 1.193 + void set_num_gc_threads(int count) { _num_gc_threads = count; } 1.194 + 1.195 + void gc_begin(bool recordGCBeginTime, bool recordPreGCUsage, 1.196 + bool recordAccumulatedGCTime); 1.197 + void gc_end(bool recordPostGCUsage, bool recordAccumulatedGCTime, 1.198 + bool recordGCEndTime, bool countCollection, GCCause::Cause cause); 1.199 + 1.200 + void reset_gc_stat() { _num_collections = 0; _accumulated_timer.reset(); } 1.201 + 1.202 + // Copy out _last_gc_stat to the given destination, returning 1.203 + // the collection count. Zero signifies no gc has taken place. 1.204 + size_t get_last_gc_stat(GCStatInfo* dest); 1.205 + 1.206 + void set_notification_enabled(bool enabled) { _notification_enabled = enabled; } 1.207 + bool is_notification_enabled() { return _notification_enabled; } 1.208 + virtual MemoryManager::Name kind() = 0; 1.209 +}; 1.210 + 1.211 +// These subclasses of GCMemoryManager are defined to include 1.212 +// GC-specific information. 1.213 +// TODO: Add GC-specific information 1.214 +class CopyMemoryManager : public GCMemoryManager { 1.215 +private: 1.216 +public: 1.217 + CopyMemoryManager() : GCMemoryManager() {} 1.218 + 1.219 + MemoryManager::Name kind() { return MemoryManager::Copy; } 1.220 + const char* name() { return "Copy"; } 1.221 +}; 1.222 + 1.223 +class MSCMemoryManager : public GCMemoryManager { 1.224 +private: 1.225 +public: 1.226 + MSCMemoryManager() : GCMemoryManager() {} 1.227 + 1.228 + MemoryManager::Name kind() { return MemoryManager::MarkSweepCompact; } 1.229 + const char* name() { return "MarkSweepCompact"; } 1.230 + 1.231 +}; 1.232 + 1.233 +class ParNewMemoryManager : public GCMemoryManager { 1.234 +private: 1.235 +public: 1.236 + ParNewMemoryManager() : GCMemoryManager() {} 1.237 + 1.238 + MemoryManager::Name kind() { return MemoryManager::ParNew; } 1.239 + const char* name() { return "ParNew"; } 1.240 + 1.241 +}; 1.242 + 1.243 +class CMSMemoryManager : public GCMemoryManager { 1.244 +private: 1.245 +public: 1.246 + CMSMemoryManager() : GCMemoryManager() {} 1.247 + 1.248 + MemoryManager::Name kind() { return MemoryManager::ConcurrentMarkSweep; } 1.249 + const char* name() { return "ConcurrentMarkSweep";} 1.250 + 1.251 +}; 1.252 + 1.253 +class PSScavengeMemoryManager : public GCMemoryManager { 1.254 +private: 1.255 +public: 1.256 + PSScavengeMemoryManager() : GCMemoryManager() {} 1.257 + 1.258 + MemoryManager::Name kind() { return MemoryManager::PSScavenge; } 1.259 + const char* name() { return "PS Scavenge"; } 1.260 + 1.261 +}; 1.262 + 1.263 +class PSMarkSweepMemoryManager : public GCMemoryManager { 1.264 +private: 1.265 +public: 1.266 + PSMarkSweepMemoryManager() : GCMemoryManager() {} 1.267 + 1.268 + MemoryManager::Name kind() { return MemoryManager::PSMarkSweep; } 1.269 + const char* name() { return "PS MarkSweep"; } 1.270 +}; 1.271 + 1.272 +class G1YoungGenMemoryManager : public GCMemoryManager { 1.273 +private: 1.274 +public: 1.275 + G1YoungGenMemoryManager() : GCMemoryManager() {} 1.276 + 1.277 + MemoryManager::Name kind() { return MemoryManager::G1YoungGen; } 1.278 + const char* name() { return "G1 Young Generation"; } 1.279 +}; 1.280 + 1.281 +class G1OldGenMemoryManager : public GCMemoryManager { 1.282 +private: 1.283 +public: 1.284 + G1OldGenMemoryManager() : GCMemoryManager() {} 1.285 + 1.286 + MemoryManager::Name kind() { return MemoryManager::G1OldGen; } 1.287 + const char* name() { return "G1 Old Generation"; } 1.288 +}; 1.289 + 1.290 +#endif // SHARE_VM_SERVICES_MEMORYMANAGER_HPP