目录
一、MemoryPool
1、定义
2、oops_do
3、get_memory_pool_instance
4、MemoryUsage / ThresholdSupport / SensorInfo
二、MemoryManager
1、定义
2、get_memory_manager_instance
三、GCMemoryManager
1、定义
2、gc_begin/gc_end
3、GCNotifier pushNotification 和 sendNotificationInternal
四、MemoryService
1、set_universe_heap
2、gc_begin / gc_end
上一篇《Hotspot 内存管理之CodeCache 源码解析》讲解了CodeCache::initialize()方法的实现,当CodeCache的_heap属性通过CodeHeap::reserve方法初始化完成后就会调用MemoryService::add_code_heap_memory_pool方法将这个_heap管理起来,如下图:
MemoryService负责缓存JVM中所有的类似CodeCache这样的大块内存的内存使用和GC的数据,主要为java.lang.management API提供内存管理相关接口的底层实现,本篇博客就详细探讨MemoryService相关类的使用与实现。
MemoryPool代表一块由JVM管理的内存区域,可以在运行时由JVM创建或者移除。MemoryPool只有两种类型,Heap或者NonHeap,通过枚举PoolType表示,部分MemoryPool可能同时属于这两种类型。MemoryPool的定义位于hotspot src/shared/vm/service/memoryPool.hpp中,其包含的属性如下:
MemoryPool定义的方法都是操作相关属性的,重点关注oops_do和get_memory_pool_instance的实现即可。
MemoryPool的类继承关系如下:
其中CodeHeapPool对应于CodeCache管理的内存,CollectedMemoryPool及其子类对应分配Java对象的堆内存,CompressedKlassSpacePool对应于保存压缩的Klass信息的内存,MetaspacePool对应保存元数据的内存。
oops_do方法用于GC时遍历对象引用的,其调用链如下:
该方法的实现如下:
void MemoryPool::oops_do(OopClosure* f) {
f->do_oop((oop*) &_memory_pool_obj);
if (_usage_sensor != NULL) {
_usage_sensor->oops_do(f);
}
if (_gc_usage_sensor != NULL) {
_gc_usage_sensor->oops_do(f);
}
}
void SensorInfo::oops_do(OopClosure* f) {
f->do_oop((oop*) &_sensor_obj);
}
即分别以_memory_pool_obj和_usage_sensor/_gc_usage_sensor中的_sensor_obj对象为根对象遍历,找到所有引用了这三个对象的对象。这三个在MemoryPool构造时都是NULL,构造方法实现如下:
_memory_pool_obj属性的初始化参考下面的get_memory_pool_instance方法的说明,_usage_sensor和_gc_usage_sensor都是通过对应的set方法实现,如下图:
以 set_usage_sensor_obj方法的调用链为例说明,如下图:
jmm_interface就是JVM提供的用于获取内存使用情况,Java线程运行等的接口,是 java.lang.management API在JVM层的具体实现,jmm_interface的定义位于同目录的jmm.h中,搜索其中SetPoolSensor方法的调用链如下:
调用的代码如下:
这就是JNI本地方法的实现,对应的类sun.management.MemoryPoolImpl就是java.lang.management.MemoryPoolMXBean的具体实现类,可通过java.lang.management.ManagementFactory.getMemoryPoolMXBeans方法获取。
get_memory_pool_instance用于创建一个对应的MemoryPoolImpl类的实例,从而可以通过java.lang.management API获取该MemoryPool的内存使用情况,其源码说明如下:
instanceOop MemoryPool::get_memory_pool_instance(TRAPS) {
// load_ptr_acquire是将其强转成volatile指针,即获取该值的最新值
instanceOop pool_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_pool_obj);
if (pool_obj == NULL) {
// 获取sun_management_ManagementFactory对应的Klass
Klass* k = Management::sun_management_ManagementFactory_klass(CHECK_NULL);
instanceKlassHandle ik(THREAD, k);
//创建一个Java String对象
Handle pool_name = java_lang_String::create_from_str(_name, CHECK_NULL);
jlong usage_threshold_value = (_usage_threshold->is_high_threshold_supported() ? 0 : -1L);
jlong gc_usage_threshold_value = (_gc_usage_threshold->is_high_threshold_supported() ? 0 : -1L);
JavaValue result(T_OBJECT);
JavaCallArguments args;
//方法参数
args.push_oop(pool_name); // Argument 1
args.push_int((int) is_heap()); // Argument 2
//方法名
Symbol* method_name = vmSymbols::createMemoryPool_name();
//方法签名
Symbol* signature = vmSymbols::createMemoryPool_signature();
args.push_long(usage_threshold_value); // Argument 3
args.push_long(gc_usage_threshold_value); // Argument 4
//调用createMemoryPool(String name, boolean isHeap, long uThreshold, long gcThreshold)方法
JavaCalls::call_static(&result,
ik,
method_name,
signature,
&args,
CHECK_NULL);
//获取createMemoryPool方法的执行结果
instanceOop p = (instanceOop) result.get_jobject();
instanceHandle pool(THREAD, p);
{
//获取锁,
MutexLocker ml(Management_lock);
//如果其他线程已经创建了该实例则返回
pool_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_pool_obj);
if (pool_obj != NULL) {
return pool_obj;
}
pool_obj = pool();
//原子的设置_memory_pool_obj属性
OrderAccess::release_store_ptr(&_memory_pool_obj, pool_obj);
}
}
return pool_obj;
}
get_memory_pool_instance实际调用的Java方法如下图:
get_memory_pool_instance的调用链如下:
jmmInterface_1_的GetMemoryPools方法的调用链如下:
MemoryUsage的定义在hotspot src/shared/vm/service/memoryUsage.hpp中, 对应Java类是java.lang.management.MemoryUsage,两者的属性是一一对应,如下图:
其中initSize表示初始大小,used表示已经使用的大小,committed表示已经分配内存可以被JVM直接利用的空间大小,committed会随着时间变化而变化,但肯定大于used,maxSize表示能够使用的最大的空间大小。
SensorInfo的定义位于同目录的lowMemoryDetector.hpp中,对应的Java类是sun.management.Sensor,这是一个抽象类,sun.management.MemoryPoolImpl中定义了两个内部实现类,PoolSensor和CollectionSensor。参考MemoryPoolImpl的初始化,如下图:
PoolSensor和CollectionSensor的核心动作就是发送消息,如下图:
可以通过javax.management.StandardEmitterMBean.addNotificationListener方法增加监听消息。当某个MemoryPool的内存使用率超过设置的阈值时就会通过Sensor发送消息。
ThresholdSupport的定义在同目录的lowMemoryDetector.hpp中,该类没有对应的Java类,有对应的设置阈值的Java方法,java.lang.management.MemoryPoolMXBean.setUsageThreshold(long threshold)和setCollectionUsageThreshold(long threshold)方法,其中setUsageThreshold的方法实现如下:
MemoryManager的定义位于hotspot src/shared/vm/service/memoryManager.hpp中,MemoryManager用来管理一个或者多个MemoryPool,垃圾回收器就是典型的MemoryManager。JVM有多个MemoryManager,一个MemoryPool可以被一个或者多个MemoryManager管理。MemoryManager定义的属性如下:
max_num_pools是一个枚举值,值是10,_memory_mgr_obj表示一个与之对应的Java对象。
MemoryManager的类继承关系如下:
为了能够方便区分MemoryManager的类型,MemoryManager定义了一个kind方法,该方法返回一个枚举值MemoryManager::Name来表示MemoryManager的类型,其定义如下:
MemoryManager定义的方法比较简单,重点关注get_memory_manager_instance的实现。
get_memory_manager_instance的用法同MemoryPool的get_memory_pool_instance方法,返回一个属性_memory_mgr_obj,如果为空则创建一个与之关联的Java对象,对应的Java类是java.lang.management.MemoryManagerMXBean或者java.lang.management.GarbageCollectorMXBean,该方法的源码说明如下:
instanceOop MemoryManager::get_memory_manager_instance(TRAPS) {
//获取属性_memory_mgr_obj的最新值
instanceOop mgr_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_mgr_obj);
if (mgr_obj == NULL) {
// 获取Java类sun_management_ManagementFactory
Klass* k = Management::sun_management_ManagementFactory_klass(CHECK_0);
instanceKlassHandle ik(THREAD, k);
//创建当前MemoryManager的名字对应的String
Handle mgr_name = java_lang_String::create_from_str(name(), CHECK_0);
JavaValue result(T_OBJECT);
JavaCallArguments args;
//只有一个参数,MemoryManager的名字
args.push_oop(mgr_name); // Argument 1
Symbol* method_name = NULL;
Symbol* signature = NULL;
//如果是gc_memory_manager,GCMemoryManager及其子类返回true,其他的返回false
if (is_gc_memory_manager()) {
//createGarbageCollector方法的方法名和方法签名
method_name = vmSymbols::createGarbageCollector_name();
signature = vmSymbols::createGarbageCollector_signature();
//放一个空对象
args.push_oop(Handle()); // Argument 2 (for future extension)
} else {
//createMemoryManager方法的方法名和签名
method_name = vmSymbols::createMemoryManager_name();
signature = vmSymbols::createMemoryManager_signature();
}
//调用Java方法
JavaCalls::call_static(&result,
ik,
method_name,
signature,
&args,
CHECK_0);
//获取调用结果
instanceOop m = (instanceOop) result.get_jobject();
instanceHandle mgr(THREAD, m);
{
//如果其他线程已经完成初始化
mgr_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_mgr_obj);
if (mgr_obj != NULL) {
return mgr_obj;
}
//更新属性值
mgr_obj = mgr();
OrderAccess::release_store_ptr(&_memory_mgr_obj, mgr_obj);
}
}
return mgr_obj;
}
调用的Java方法的如下图:
get_memory_manager_instance的调用链如下:
最后一个GetMemoryManagers方法的调用链如下:
CodeCacheMemoryManager和MetaspaceMemoryManager继承自MemoryManager,只是修改了kind和name方法的返回值而已,GCMemoryManager在 MemoryManager的基础上增加了部分跟GC相关的字段,如下:
GCMemoryManager定义的方法都是属性相关的,重点关注其中的gc_begin/gc_end方法的实现即可。
GCStatInfo和 GCMemoryManager都位于memoryManager.hpp中,其定义的属性如下:
参考set_before_gc_usage方法的源码,如下:
void set_before_gc_usage(int pool_index, MemoryUsage usage) {
assert(pool_index >= 0 && pool_index < _usage_array_size, "Range checking");
set_gc_usage(pool_index, usage, true /* before gc */);
}
void GCStatInfo::set_gc_usage(int pool_index, MemoryUsage usage, bool before_gc) {
MemoryUsage* gc_usage_array;
if (before_gc) {
gc_usage_array = _before_gc_usage_array;
} else {
gc_usage_array = _after_gc_usage_array;
}
gc_usage_array[pool_index] = usage;
}
gc_begin方法用于在GC开始前记录MemoryPool的使用情况,gc_end用于在GC结束后记录MemoryPool的使用情况,两者的调用链如下:
即通过TraceMemoryManagerStats类的构造方法调用gc_begin,析构方法调用gc_end。这两方法的源码实现如下:
void GCMemoryManager::gc_begin(bool recordGCBeginTime, bool recordPreGCUsage,
bool recordAccumulatedGCTime) {
assert(_last_gc_stat != NULL && _current_gc_stat != NULL, "Just checking");
//如果统计累计GC时间
if (recordAccumulatedGCTime) {
_accumulated_timer.start();
}
//如果记录GC开始时间
if (recordGCBeginTime) {
_current_gc_stat->set_index(_num_collections+1);
_current_gc_stat->set_start_time(Management::timestamp());
}
//如果在GC前记录内存使用情况
if (recordPreGCUsage) {
//遍历所有的MemoryPool
for (int i = 0; i < MemoryService::num_memory_pools(); i++) {
MemoryPool* pool = MemoryService::get_memory_pool(i);
MemoryUsage usage = pool->get_memory_usage();
//GC前的MemoryUsage
_current_gc_stat->set_before_gc_usage(i, usage);
//打印日志
HS_DTRACE_PROBE8(hotspot, mem__pool__gc__begin,
name(), strlen(name()),
pool->name(), strlen(pool->name()),
usage.init_size(), usage.used(),
usage.committed(), usage.max_size());
}
}
}
//垃圾回收器因为某些原因终止了也要调用此方法
void GCMemoryManager::gc_end(bool recordPostGCUsage,
bool recordAccumulatedGCTime,
bool recordGCEndTime, bool countCollection,
GCCause::Cause cause,
bool allMemoryPoolsAffected) {
//记录GC累计时间
if (recordAccumulatedGCTime) {
_accumulated_timer.stop();
}
//记录GC结束时间
if (recordGCEndTime) {
_current_gc_stat->set_end_time(Management::timestamp());
}
if (recordPostGCUsage) {
int i;
//遍历所有MemoryPool
for (i = 0; i < MemoryService::num_memory_pools(); i++) {
MemoryPool* pool = MemoryService::get_memory_pool(i);
MemoryUsage usage = pool->get_memory_usage();
//打印日志
HS_DTRACE_PROBE8(hotspot, mem__pool__gc__end,
name(), strlen(name()),
pool->name(), strlen(pool->name()),
usage.init_size(), usage.used(),
usage.committed(), usage.max_size());
//记录GC后的内存使用
_current_gc_stat->set_after_gc_usage(i, usage);
}
//遍历所有MemoryPool
for (i = 0; i < num_memory_pools(); i++) {
MemoryPool* pool = get_memory_pool(i);
MemoryUsage usage = pool->get_memory_usage();
// Compare with GC usage threshold
if (allMemoryPoolsAffected || pool_always_affected_by_gc(i)) {
//更新GC后的内存使用情况
pool->set_last_collection_usage(usage);
//判断是否超过阈值,增加SensorInfo中的计数器
LowMemoryDetector::detect_after_gc_memory(pool);
}
}
}
if (countCollection) {
_num_collections++;
//重置_last_gc_stat和_current_gc_stat
{
MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag);
GCStatInfo *tmp = _last_gc_stat;
_last_gc_stat = _current_gc_stat;
_current_gc_stat = tmp;
// reset the current stat for diagnosability purposes
_current_gc_stat->clear();
}
if (is_notification_enabled()) {
bool isMajorGC = this == MemoryService::get_major_gc_manager();
//添加一个待发送的通知消息,该消息最终通过GCNotifier::sendNotificationInternal方法发送出去,
//该方法最终调用sun_management_GarbageCollectorImpl类的createGCNotification方法
GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC",
GCCause::to_string(cause));
}
}
}
pushNotification用于创建一个GC通知消息,将其放入队列中;sendNotificationInternal用于从队列中获取并发送GC通知消息,由内部线程ServiceThread不断执行,这两方法的源码如下:
void GCNotifier::pushNotification(GCMemoryManager *mgr, const char *action, const char *cause) {
int num_pools = MemoryService::num_memory_pools();
//创建一个新的GCStatInfo
GCStatInfo* stat = new(ResourceObj::C_HEAP, mtGC) GCStatInfo(num_pools);
//将上一次GC的GCStatInfo复制到这个新的实例中
mgr->get_last_gc_stat(stat);
//创建一个新的GC通知
GCNotificationRequest *request = new GCNotificationRequest(os::javaTimeMillis(),mgr,action,cause,stat);
//添加到缓存队列中
addRequest(request);
}
void GCNotifier::addRequest(GCNotificationRequest *request) {
//获取Service_lock
MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
if(first_request == NULL) {
first_request = request;
} else {
last_request->next = request;
}
last_request = request;
Service_lock->notify_all();
}
GCNotificationRequest *GCNotifier::getRequest() {
MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
GCNotificationRequest *request = first_request;
//更新first_request,即按照添加的顺序依次处理
if(first_request != NULL) {
first_request = first_request->next;
}
return request;
}
void GCNotifier::sendNotificationInternal(TRAPS) {
ResourceMark rm(THREAD);
HandleMark hm(THREAD);
//获取待发送的一个GC通知消息
GCNotificationRequest *request = getRequest();
if (request != NULL) {
NotificationMark nm(request);
//创建一个com_sun_management_GcInfo类实例
Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, CHECK);
//初始化其他的方法参数
Handle objName = java_lang_String::create_from_str(request->gcManager->name(), CHECK);
Handle objAction = java_lang_String::create_from_str(request->gcAction, CHECK);
Handle objCause = java_lang_String::create_from_str(request->gcCause, CHECK);
Klass* k = Management::sun_management_GarbageCollectorImpl_klass(CHECK);
instanceKlassHandle gc_mbean_klass(THREAD, k);
instanceOop gc_mbean = request->gcManager->get_memory_manager_instance(THREAD);
instanceHandle gc_mbean_h(THREAD, gc_mbean);
//校验gc_mbean必须是sun_management_GarbageCollectorImpl实例
if (!gc_mbean_h->is_a(k)) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"This GCMemoryManager doesn't have a GarbageCollectorMXBean");
}
JavaValue result(T_VOID);
JavaCallArguments args(gc_mbean_h);
//设置方法参数
args.push_long(request->timestamp);
args.push_oop(objName);
args.push_oop(objAction);
args.push_oop(objCause);
args.push_oop(objGcInfo);
//调用sun_management_GarbageCollectorImpl的createGCNotification方法
JavaCalls::call_virtual(&result,
gc_mbean_klass,
vmSymbols::createGCNotification_name(),
vmSymbols::createGCNotification_signature(),
&args,
CHECK);
}
}
同内存使用超过阈值的触发的消息,执行GC后发送的消息的监听也可通过javax.management.StandardEmitterMBean.addNotificationListener方法增加消息的监听逻辑。
sendNotificationInternal的调用链如下:
MemoryService定义在hotspot src/shared/vm/service/memoryService .hpp中,其定义的方法都是静态工具方法,提供MemoryPool和MemoryManager相关的统一入口方法。其定义的static属性如下:
重点关注以下方法的实现。
set_universe_heap在是CollectedHeap初始化完成后调用的,用来设置CollectedHeap对应的MemoryPool和GCMemoryManager,其调用链如下:
其源码说明如下:
void MemoryService::set_universe_heap(CollectedHeap* heap) {
CollectedHeap::Name kind = heap->kind();
//区分不同的堆类型,分别处理
switch (kind) {
case CollectedHeap::GenCollectedHeap : {
add_gen_collected_heap_info(GenCollectedHeap::heap());
break;
}
#if INCLUDE_ALL_GCS
case CollectedHeap::ParallelScavengeHeap : {
add_parallel_scavenge_heap_info(ParallelScavengeHeap::heap());
break;
}
case CollectedHeap::G1CollectedHeap : {
add_g1_heap_info(G1CollectedHeap::heap());
break;
}
#endif // INCLUDE_ALL_GCS
default: {
guarantee(false, "Unrecognized kind of heap");
}
}
//会遍历所有的GC线程
GcThreadCountClosure gctcc;
heap->gc_threads_do(&gctcc);
int count = gctcc.count();
if (count > 0) {
//设置GC线程数
_minor_gc_manager->set_num_gc_threads(count);
_major_gc_manager->set_num_gc_threads(count);
}
//初始化GCStatInfo
_minor_gc_manager->initialize_gc_stat_info();
_major_gc_manager->initialize_gc_stat_info();
}
void MemoryService::add_gen_collected_heap_info(GenCollectedHeap* heap) {
CollectorPolicy* policy = heap->collector_policy();
assert(policy->is_two_generation_policy(), "Only support two generations");
guarantee(heap->n_gens() == 2, "Only support two-generation heap");
TwoGenerationCollectorPolicy* two_gen_policy = policy->as_two_generation_policy();
if (two_gen_policy != NULL) {
GenerationSpec** specs = two_gen_policy->generations();
Generation::Name kind = specs[0]->name();
//区分不同的Generation设置_minor_gc_manager
switch (kind) {
case Generation::DefNew:
_minor_gc_manager = MemoryManager::get_copy_memory_manager();
break;
#if INCLUDE_ALL_GCS
case Generation::ParNew:
case Generation::ASParNew:
_minor_gc_manager = MemoryManager::get_parnew_memory_manager();
break;
#endif // INCLUDE_ALL_GCS
default:
guarantee(false, "Unrecognized generation spec");
break;
}
//设置_major_gc_manager
if (policy->is_mark_sweep_policy()) {
_major_gc_manager = MemoryManager::get_msc_memory_manager();
#if INCLUDE_ALL_GCS
} else if (policy->is_concurrent_mark_sweep_policy()) {
_major_gc_manager = MemoryManager::get_cms_memory_manager();
#endif // INCLUDE_ALL_GCS
} else {
guarantee(false, "Unknown two-gen policy");
}
} else {
guarantee(false, "Non two-gen policy");
}
//添加manager
_managers_list->append(_minor_gc_manager);
_managers_list->append(_major_gc_manager);
//区分不同的Generation,为eden和survivor区分别创建适配的MemoryPool,并添加到_pools_list中
//参考add_psYoung_memory_pool方法的实现
add_generation_memory_pool(heap->get_gen(minor), _major_gc_manager, _minor_gc_manager);
add_generation_memory_pool(heap->get_gen(major), _major_gc_manager);
}
void MemoryService::add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap) {
//设置对应的_minor_gc_manager和_major_gc_manager
_minor_gc_manager = MemoryManager::get_psScavenge_memory_manager();
_major_gc_manager = MemoryManager::get_psMarkSweep_memory_manager();
_managers_list->append(_minor_gc_manager);
_managers_list->append(_major_gc_manager);
//为eden和survivor区分别创建适配的MemoryPool,并添加到_pools_list中
add_psYoung_memory_pool(heap->young_gen(), _major_gc_manager, _minor_gc_manager);
add_psOld_memory_pool(heap->old_gen(), _major_gc_manager);
}
void MemoryService::add_g1_heap_info(G1CollectedHeap* g1h) {
assert(UseG1GC, "sanity");
//设置对应的_minor_gc_manager和_major_gc_manager
_minor_gc_manager = MemoryManager::get_g1YoungGen_memory_manager();
_major_gc_manager = MemoryManager::get_g1OldGen_memory_manager();
_managers_list->append(_minor_gc_manager);
_managers_list->append(_major_gc_manager);
//为eden和survivor区分别创建适配的MemoryPool,并添加到_pools_list中
add_g1YoungGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager);
add_g1OldGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager);
}
void MemoryService::add_psYoung_memory_pool(PSYoungGen* gen,
GCMemoryManager* major_mgr,
GCMemoryManager* minor_mgr) {
assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
// Add a memory pool for each space and young gen doesn't
// support low memory detection as it is expected to get filled up.
EdenMutableSpacePool* eden = new EdenMutableSpacePool(gen,
gen->eden_space(),
"PS Eden Space",
MemoryPool::Heap,
false /* support_usage_threshold */);
SurvivorMutableSpacePool* survivor = new SurvivorMutableSpacePool(gen,
"PS Survivor Space",
MemoryPool::Heap,
false /* support_usage_threshold */);
major_mgr->add_pool(eden);
major_mgr->add_pool(survivor);
minor_mgr->add_pool(eden);
minor_mgr->add_pool(survivor);
_pools_list->append(eden);
_pools_list->append(survivor);
}
gc_begin和gc_end方法是对GCMemoryManager的gc_begin和gc_end的再封装,其源码实现如下:
void MemoryService::gc_begin(bool fullGC, bool recordGCBeginTime,
bool recordAccumulatedGCTime,
bool recordPreGCUsage, bool recordPeakUsage) {
GCMemoryManager* mgr;
//根据是否fullGC找到对应的GCMemoryManager
if (fullGC) {
mgr = _major_gc_manager;
} else {
mgr = _minor_gc_manager;
}
assert(mgr->is_gc_memory_manager(), "Sanity check");
//执行gc_begin
mgr->gc_begin(recordGCBeginTime, recordPreGCUsage, recordAccumulatedGCTime);
if (recordPeakUsage) {
for (int i = 0; i < _pools_list->length(); i++) {
MemoryPool* pool = _pools_list->at(i);
//记录GC开始前的内存使用
pool->record_peak_memory_usage();
}
}
}
void MemoryService::gc_end(bool fullGC, bool recordPostGCUsage,
bool recordAccumulatedGCTime,
bool recordGCEndTime, bool countCollection,
GCCause::Cause cause,
bool allMemoryPoolsAffected) {
GCMemoryManager* mgr;
if (fullGC) {
mgr = (GCMemoryManager*) _major_gc_manager;
} else {
mgr = (GCMemoryManager*) _minor_gc_manager;
}
assert(mgr->is_gc_memory_manager(), "Sanity check");
//GC完成,记录GC的耗时,GC后的内存使用情况等
mgr->gc_end(recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime,
countCollection, cause, allMemoryPoolsAffected);
}
void MemoryPool::record_peak_memory_usage() {
// 将当前的内存使用的各项指标跟历史最大值比,取最大值
MemoryUsage usage = get_memory_usage();
size_t peak_used = get_max_value(usage.used(), _peak_usage.used());
size_t peak_committed = get_max_value(usage.committed(), _peak_usage.committed());
size_t peak_max_size = get_max_value(usage.max_size(), _peak_usage.max_size());
//创建新的MemoryUsage
_peak_usage = MemoryUsage(initial_size(), peak_used, peak_committed, peak_max_size);
}
上述方法涉及了垃圾回收相关的多个数据结构,这些类的具体用法后面的博客会详细介绍,此处只是了解一个整体的轮廓。