本篇开始讲解表示分代堆内存的GenCollectedHeap的实现细节。
1、定义
GenCollectedHeap的定义在hotspot\src\share\vm\memory\genCollectedHeap.hpp中,其类继承关系如下:
其中CollectedHeap的讲解参考《Hotspot 垃圾回收之CollectedHeap 源码解析》 ,SharedHeap新增的属性如下:
- static SharedHeap* _sh; //静态SharedHeap实例
- GenRemSet* _rem_set; //卡表实现
- CollectorPolicy *_collector_policy; //垃圾回收策略
- int _strong_roots_parity; //遍历Java线程包含的oop使用的
- FlexibleWorkGang* _workers; //执行并行GC的线程池
- bool _thread_holds_heap_lock_for_gc;
GenCollectedHeap新增的属性如下:
- static GenCollectedHeap* _gch; //静态GenCollectedHeap实例
- int _n_gens; //包含的Generation的个数,通常是2
- Generation* _gens[max_gens]; //Generation数组
- GenerationSpec** _gen_specs; //用来初始化Generation的GenerationSpec数组
- GenCollectorPolicy* _gen_policy; //垃圾回收策略
- bool _incremental_collection_failed; // 执行promote是否会失败
- unsigned int _full_collections_completed; //已经执行万恒的Full GC的次数
- SubTasksDone* _process_strong_tasks; //用于控制根节点遍历任务的并行执行
其中max_gens是一个常量枚举,其定义如下:
image.png除此之外还有一个表示并行执行任务的序号的枚举GCH_strong_roots_tasks,其定义如下:
image.png
重点关垃圾回收相关方法的实现。
2、构造方法 / initialize / post_initialize
这三个方法按照顺序依次调用,用来初始化GenCollectedHeap,其实现如下:
GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) :
SharedHeap(policy),
_gen_policy(policy),
_process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
_full_collections_completed(0)
{
assert(policy != NULL, "Sanity check");
}
SharedHeap::SharedHeap(CollectorPolicy* policy_) :
CollectedHeap(),
_collector_policy(policy_),
_rem_set(NULL),
_strong_roots_parity(0),
_workers(NULL)
{
//初始化静态属性_sh
_sh = this; // ch is static, should be set only once.
if ((UseParNewGC ||
(UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled ||
CMSParallelRemarkEnabled)) ||
UseG1GC) &&
ParallelGCThreads > 0) {
//初始化执行并行GC的线程池
_workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
/* are_GC_task_threads */true,
/* are_ConcurrentGC_threads */false);
if (_workers == NULL) {
vm_exit_during_initialization("Failed necessary allocation.");
} else {
_workers->initialize_workers();
}
}
}
GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) :
SharedHeap(policy),
_gen_policy(policy),
_process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
_full_collections_completed(0)
{
assert(policy != NULL, "Sanity check");
}
jint GenCollectedHeap::initialize() {
CollectedHeap::pre_initialize();
int i;
//_n_gens表示有多少代,通常是2代,年轻代和老年代
_n_gens = gen_policy()->number_of_generations();
guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize");
size_t gen_alignment = Generation::GenGrain;
_gen_specs = gen_policy()->generations();
for (i = 0; i < _n_gens; i++) {
//将内存的初始值和最大值按照内存分配粒度对齐
_gen_specs[i]->align(gen_alignment);
}
char* heap_address;
size_t total_reserved = 0;
int n_covered_regions = 0;
ReservedSpace heap_rs;
size_t heap_alignment = collector_policy()->heap_alignment();
//根据各GenerationSpec的最大大小计算总的需要保留的内存空间,然后申请指定大小的连续内存空间
heap_address = allocate(heap_alignment, &total_reserved,
&n_covered_regions, &heap_rs);
if (!heap_rs.is_reserved()) {
//申请失败
vm_shutdown_during_initialization(
"Could not reserve enough space for object heap");
return JNI_ENOMEM;
}
//设置_reserved相关属性
_reserved = MemRegion((HeapWord*)heap_rs.base(),
(HeapWord*)(heap_rs.base() + heap_rs.size()));
_reserved.set_word_size(0);
_reserved.set_start((HeapWord*)heap_rs.base());
size_t actual_heap_size = heap_rs.size();
_reserved.set_end((HeapWord*)(heap_rs.base() + actual_heap_size));
//初始化GenRemSet
_rem_set = collector_policy()->create_rem_set(_reserved, n_covered_regions);
set_barrier_set(rem_set()->bs());
_gch = this;
for (i = 0; i < _n_gens; i++) {
//初始化各Generation
ReservedSpace this_rs = heap_rs.first_part(_gen_specs[i]->max_size(), false, false);
_gens[i] = _gen_specs[i]->init(this_rs, i, rem_set());
heap_rs = heap_rs.last_part(_gen_specs[i]->max_size());
}
//将_incremental_collection_failed置为false
clear_incremental_collection_failed();
#if INCLUDE_ALL_GCS
if (collector_policy()->is_concurrent_mark_sweep_policy()) {
//如果是CMS则创建CMSCollector
bool success = create_cms_collector();
if (!success) return JNI_ENOMEM;
}
#endif // INCLUDE_ALL_GCS
return JNI_OK;
}
char* GenCollectedHeap::allocate(size_t alignment,
size_t* _total_reserved,
int* _n_covered_regions,
ReservedSpace* heap_rs){
const char overflow_msg[] = "The size of the object heap + VM data exceeds "
"the maximum representable size";
// Now figure out the total size.
size_t total_reserved = 0;
int n_covered_regions = 0;
const size_t pageSize = UseLargePages ?
os::large_page_size() : os::vm_page_size();
assert(alignment % pageSize == 0, "Must be");
//遍历所有的_gen_specs,累加各GenerationSpec的max_size和n_covered_regions
for (int i = 0; i < _n_gens; i++) {
total_reserved += _gen_specs[i]->max_size();
if (total_reserved < _gen_specs[i]->max_size()) {
vm_exit_during_initialization(overflow_msg);
}
n_covered_regions += _gen_specs[i]->n_covered_regions();
}
//校验累加后的total_reserved已经是内存对齐的
assert(total_reserved % alignment == 0,
err_msg("Gen size; total_reserved=" SIZE_FORMAT ", alignment="
SIZE_FORMAT, total_reserved, alignment));
//加2是为卡表保留的
n_covered_regions += 2;
//赋值
*_total_reserved = total_reserved;
*_n_covered_regions = n_covered_regions;
//申请指定大小的连续内存空间
*heap_rs = Universe::reserve_heap(total_reserved, alignment);
//返回基地址
return heap_rs->base();
}
void SharedHeap::set_barrier_set(BarrierSet* bs) {
_barrier_set = bs;
oopDesc::set_bs(bs);
}
void clear_incremental_collection_failed() {
_incremental_collection_failed = false;
}
void GenCollectedHeap::post_initialize() {
SharedHeap::post_initialize();
TwoGenerationCollectorPolicy *policy =
(TwoGenerationCollectorPolicy *)collector_policy();
guarantee(policy->is_two_generation_policy(), "Illegal policy type");
//校验Generation被正确的设置了
DefNewGeneration* def_new_gen = (DefNewGeneration*) get_gen(0);
assert(def_new_gen->kind() == Generation::DefNew ||
def_new_gen->kind() == Generation::ParNew ||
def_new_gen->kind() == Generation::ASParNew,
"Wrong generation kind");
Generation* old_gen = get_gen(1);
assert(old_gen->kind() == Generation::ConcurrentMarkSweep ||
old_gen->kind() == Generation::ASConcurrentMarkSweep ||
old_gen->kind() == Generation::MarkSweepCompact,
"Wrong generation kind");
//初始化TwoGenerationCollectorPolicy
policy->initialize_size_policy(def_new_gen->eden()->capacity(),
old_gen->capacity(),
def_new_gen->from()->capacity());
policy->initialize_gc_policy_counters();
}
void SharedHeap::post_initialize() {
CollectedHeap::post_initialize();
ref_processing_init();
}
void CollectedHeap::post_initialize() {
collector_policy()->post_heap_initialize();
}
void GenCollectedHeap::ref_processing_init() {
SharedHeap::ref_processing_init();
for (int i = 0; i < _n_gens; i++) {
//初始化各代的ReferenceProcessor
_gens[i]->ref_processor_init();
}
}
Generation* get_gen(int i) const {
guarantee(i >= 0 && i < _n_gens, "Out of bounds");
return _gens[i];
}
其调用链如下:
image.pngimage.png image.png
3、do_collection
do_collection是GenCollectedHeap执行垃圾回收的核心方法,其底层核心就是各Genaration的collect方法,注意其实现如下:
void GenCollectedHeap::do_collection(bool full,
bool clear_all_soft_refs,
size_t size,
bool is_tlab,
int max_level) {
bool prepared_for_verification = false;
ResourceMark rm;
DEBUG_ONLY(Thread* my_thread = Thread::current();)
//校验处于安全点上
assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
//校验调用线程是VMThread 或者CMS Thread
assert(my_thread->is_VM_thread() ||
my_thread->is_ConcurrentGC_thread(),
"incorrect thread type capability");
//校验获取了Heap_lock锁
assert(Heap_lock->is_locked(),
"the requesting thread should have the Heap_lock");
guarantee(!is_gc_active(), "collection is not reentrant");
assert(max_level < n_gens(), "sanity check");
//检查是否有线程处于JNI关键区,check_active_before_gc返回true表示有,则终止当前GC,等待线程退出
//最后一个退出的线程会负责执行GC
if (GC_locker::check_active_before_gc()) {
return; // GC is disabled (e.g. JNI GetXXXCritical operation)
}
//是否需要清除软引用
const bool do_clear_all_soft_refs = clear_all_soft_refs ||
collector_policy()->should_clear_all_soft_refs();
//ClearedAllSoftRefs通过析构函数设置CollectorPolicy的_all_soft_refs_clear属性
ClearedAllSoftRefs casr(do_clear_all_soft_refs, collector_policy());
//获取元空间已使用内存
const size_t metadata_prev_used = MetaspaceAux::used_bytes();
//打印GC的堆内存使用情况
print_heap_before_gc();
{
//临时设置_is_gc_active为true,表示GC开始了
FlagSetting fl(_is_gc_active, true);
bool complete = full && (max_level == (n_gens()-1));
const char* gc_cause_prefix = complete ? "Full GC" : "GC";
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
GCTraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, NULL, GCId::peek());
//遍历各Generation执行GC准备工作
gc_prologue(complete);
//增加GC次数
increment_total_collections(complete);
//统计总的内存使用量
size_t gch_prev_used = used();
int starting_level = 0;
if (full) {
//找到老年代对应的level
for (int i = max_level; i >= 0; i--) {
if (_gens[i]->full_collects_younger_generations()) {
starting_level = i;
break;
}
}
}
bool must_restore_marks_for_biased_locking = false;
int max_level_collected = starting_level;
for (int i = starting_level; i <= max_level; i++) {
if (_gens[i]->should_collect(full, size, is_tlab)) {
//如果需要垃圾回收
if (i == n_gens() - 1) { // a major collection is to happen
//如果是老年代
if (!complete) {
//increment_total_collections方法只有在complete为true时才会增加_total_full_collections计数
//此处complete为false,但还是老年代的GC,所以增加计数
increment_total_full_collections();
}
//根据参数配置dump
pre_full_gc_dump(NULL); // do any pre full gc dumps
}
GCTraceTime t1(_gens[i]->short_name(), PrintGCDetails, false, NULL, GCId::peek());
TraceCollectorStats tcs(_gens[i]->counters());
TraceMemoryManagerStats tmms(_gens[i]->kind(),gc_cause());
size_t prev_used = _gens[i]->used();
//增加计数
_gens[i]->stat_record()->invocations++;
_gens[i]->stat_record()->accumulated_time.start();
//记录各Generation的Space的top指针,生产版本为空实现
record_gen_tops_before_GC();
if (PrintGC && Verbose) {
gclog_or_tty->print("level=%d invoke=%d size=" SIZE_FORMAT,
i,
_gens[i]->stat_record()->invocations,
size*HeapWordSize);
}
if (VerifyBeforeGC && i >= VerifyGCLevel &&
total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification
if (!prepared_for_verification) {
prepare_for_verify();
prepared_for_verification = true;
}
Universe::verify(" VerifyBeforeGC:");
}
COMPILER2_PRESENT(DerivedPointerTable::clear());
if (!must_restore_marks_for_biased_locking &&
//DefNewGeneration返回false,ConcurrentMarkSweepGeneration采用父类默认实现返回true
_gens[i]->performs_in_place_marking()) {
must_restore_marks_for_biased_locking = true;
//将各线程的持有偏向锁的oop的对象头保存起来
BiasedLocking::preserve_marks();
}
// Do collection work
{
HandleMark hm; // Discard invalid handles created during gc
save_marks(); // save marks for all gens
ReferenceProcessor* rp = _gens[i]->ref_processor();
if (rp->discovery_is_atomic()) {
rp->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
rp->setup_policy(do_clear_all_soft_refs);
} else {
//collect方法会调用enable_discovery方法
}
//执行垃圾回收
_gens[i]->collect(full, do_clear_all_soft_refs, size, is_tlab);
if (!rp->enqueuing_is_done()) {
//enqueuing_is_done为false
//将处理后剩余的References实例加入到pending-list中
rp->enqueue_discovered_references();
} else {
//enqueuing_is_done为true,已经加入到pending-list中了,将其恢复成默认值
rp->set_enqueuing_is_done(false);
}
rp->verify_no_references_recorded();
}
max_level_collected = i;
// Determine if allocation request was met.
if (size > 0) {
if (!is_tlab || _gens[i]->supports_tlab_allocation()) {
if (size*HeapWordSize <= _gens[i]->unsafe_max_alloc_nogc()) {
size = 0;
}
}
}
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
_gens[i]->stat_record()->accumulated_time.stop();
//更新各Generation的GC统计信息
update_gc_stats(i, full);
if (VerifyAfterGC && i >= VerifyGCLevel &&
total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification
Universe::verify(" VerifyAfterGC:");
}
if (PrintGCDetails) {
gclog_or_tty->print(":");
_gens[i]->print_heap_change(prev_used);
}
}
}//for循环结束
//是否Full GC
complete = complete || (max_level_collected == n_gens() - 1);
if (complete) { // We did a "major" collection
//根据配置dump
post_full_gc_dump(NULL); // do any post full gc dumps
}
if (PrintGCDetails) {
print_heap_change(gch_prev_used);
if (complete) {
MetaspaceAux::print_metaspace_change(metadata_prev_used);
}
}
for (int j = max_level_collected; j >= 0; j -= 1) {
//调整各Generation的容量
_gens[j]->compute_new_size();
}
if (complete) {
//删掉被卸载的ClassLoader实例及其相关元数据
ClassLoaderDataGraph::purge();
MetaspaceAux::verify_metrics();
//重置元空间大小
MetaspaceGC::compute_new_size();
update_full_collections_completed();
}
//跟踪GC后的内存使用
MemoryService::track_memory_usage();
gc_epilogue(complete);
if (must_restore_marks_for_biased_locking) {
BiasedLocking::restore_marks();
}
}
AdaptiveSizePolicy* sp = gen_policy()->size_policy();
AdaptiveSizePolicyOutput(sp, total_collections());
print_heap_after_gc();
#ifdef TRACESPINNING
ParallelTaskTerminator::print_termination_counts();
#endif
}
//父类方法
bool is_gc_active() const { return _is_gc_active; }
GCCause::Cause gc_cause() { return _gc_cause; }
void GenCollectedHeap::gc_prologue(bool full) {
assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer");
always_do_update_barrier = false;
//收集GC前的TLAB的统计数据
CollectedHeap::accumulate_statistics_all_tlabs();
//遍历各Generation执行ensure_parsability
ensure_parsability(true); // retire TLABs
//遍历各Generation执行gc_prologue
GenGCPrologueClosure blk(full);
generation_iterate(&blk, false); // not old-to-young.
};
void GenCollectedHeap::ensure_parsability(bool retire_tlabs) {
CollectedHeap::ensure_parsability(retire_tlabs);
GenEnsureParsabilityClosure ep_cl;
generation_iterate(&ep_cl, false);
}
//old_to_young决定了遍历的顺序,如果为true则先遍历老年代再遍历年轻代
void GenCollectedHeap::generation_iterate(GenClosure* cl,
bool old_to_young) {
if (old_to_young) {
for (int i = _n_gens-1; i >= 0; i--) {
cl->do_generation(_gens[i]);
}
} else {
for (int i = 0; i < _n_gens; i++) {
cl->do_generation(_gens[i]);
}
}
}
class GenEnsureParsabilityClosure: public GenCollectedHeap::GenClosure {
public:
void do_generation(Generation* gen) {
gen->ensure_parsability();
}
};
class GenGCPrologueClosure: public GenCollectedHeap::GenClosure {
private:
bool _full;
public:
void do_generation(Generation* gen) {
gen->gc_prologue(_full);
}
GenGCPrologueClosure(bool full) : _full(full) {};
};
void increment_total_collections(bool full = false) {
//增加总的GC次数
_total_collections++;
if (full) {
//增加Full GC的次数
increment_total_full_collections();
}
}
void increment_total_full_collections() { _total_full_collections++; }
size_t GenCollectedHeap::used() const {
size_t res = 0;
//遍历各Generation累加内存使用量
for (int i = 0; i < _n_gens; i++) {
res += _gens[i]->used();
}
return res;
}
//DefNewGeneration采用父类Generation的默认实现,返回false
//ConcurrentMarkSweepGeneration的实现如下
//UseCMSCompactAtFullCollection默认为true,表示FullGC时所使用Mark-Sweep-Compact算法
//CollectGen0First默认为false,表示是否在FullGC前收集年轻代
virtual bool full_collects_younger_generations() const {
return UseCMSCompactAtFullCollection && !CollectGen0First;
}
void CollectedHeap::pre_full_gc_dump(GCTimer* timer) {
//HeapDumpBeforeFullGC默认为false
if (HeapDumpBeforeFullGC) {
GCTraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, timer, GCId::create());
HeapDumper::dump_heap();
}
//PrintClassHistogramBeforeFullGC默认为false
if (PrintClassHistogramBeforeFullGC) {
GCTraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, timer, GCId::create());
VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
inspector.doit();
}
}
#ifndef PRODUCT
class GenGCSaveTopsBeforeGCClosure: public GenCollectedHeap::GenClosure {
private:
public:
void do_generation(Generation* gen) {
gen->record_spaces_top();
}
};
void GenCollectedHeap::record_gen_tops_before_GC() {
if (ZapUnusedHeapArea) {
GenGCSaveTopsBeforeGCClosure blk;
generation_iterate(&blk, false); // not old-to-young.
}
}
#endif
void GenCollectedHeap::save_marks() {
for (int i = 0; i < _n_gens; i++) {
_gens[i]->save_marks();
}
}
void update_gc_stats(int current_level, bool full) {
for (int i = 0; i < _n_gens; i++) {
_gens[i]->update_gc_stats(current_level, full);
}
}
void CollectedHeap::post_full_gc_dump(GCTimer* timer) {
//HeapDumpAfterFullGC默认为false
if (HeapDumpAfterFullGC) {
GCTraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, timer, GCId::create());
HeapDumper::dump_heap();
}
//PrintClassHistogramAfterFullGC默认为false
if (PrintClassHistogramAfterFullGC) {
GCTraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, timer, GCId::create());
VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
inspector.doit();
}
}
unsigned int GenCollectedHeap::update_full_collections_completed() {
MonitorLockerEx ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
assert(_full_collections_completed <= _total_full_collections,
"Can't complete more collections than were started");
//获取锁FullGCCount_lock,更新_full_collections_completed属性
_full_collections_completed = _total_full_collections;
ml.notify_all();
return _full_collections_completed;
}
void GenCollectedHeap::gc_epilogue(bool full) {
#ifdef COMPILER2
assert(DerivedPointerTable::is_empty(), "derived pointer present");
size_t actual_gap = pointer_delta((HeapWord*) (max_uintx-3), *(end_addr()));
guarantee(actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps");
#endif /* COMPILER2 */
//重新计算各线程的TLAB的分配大小
resize_all_tlabs();
//遍历各Generation执行gc_epilogue方法
GenGCEpilogueClosure blk(full);
generation_iterate(&blk, false); // not old-to-young.
//CleanChunkPoolAsync默认为false
if (!CleanChunkPoolAsync) {
//清理ChunkPool
Chunk::clean_chunk_pool();
}
//更新计数器
MetaspaceCounters::update_performance_counters();
CompressedClassSpaceCounters::update_performance_counters();
always_do_update_barrier = UseConcMarkSweepGC;
};
void CollectedHeap::resize_all_tlabs() {
if (UseTLAB) {
assert(SafepointSynchronize::is_at_safepoint() ||
!is_init_completed(),
"should only resize tlabs at safepoint");
//重新计算各线程的TLAB的大小
ThreadLocalAllocBuffer::resize_all_tlabs();
}
}
class GenGCEpilogueClosure: public GenCollectedHeap::GenClosure {
private:
bool _full;
public:
void do_generation(Generation* gen) {
gen->gc_epilogue(_full);
}
GenGCEpilogueClosure(bool full) : _full(full) {};
};
上述代码中的ClearedAllSoftRefs的定义如下:
image.png
FlagSetting的定义如下:
image.png
该方法的调用链如下:
image.png
4、do_full_collection
do_full_collection有两个重载版本,用来执行年轻代或者老年代的“full gc”,即底层调用do_collection方法时,full参数是true,其实现如下:
void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs) {
do_full_collection(clear_all_soft_refs, _n_gens - 1);
}
void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs,
int max_level) {
int local_max_level;
if (!incremental_collection_will_fail(false /* don't consult_young */) && //此时返回false说明老年代空间是足够的
gc_cause() == GCCause::_gc_locker) { //如果是最后一个从JNI关键区退出的线程触发的GC,满足这两个条件则只执行年轻代的垃圾回收
local_max_level = 0;
} else {
local_max_level = max_level;
}
do_collection(true /* full */,
clear_all_soft_refs /* clear_all_soft_refs */,
0 /* size */,
false /* is_tlab */,
local_max_level /* max_level */);
//如果只执行年轻代的GC,但是因为老年满了导致GC失败,则重试
if (local_max_level == 0 && gc_cause() == GCCause::_gc_locker &&
incremental_collection_will_fail(false /* don't consult_young */)) {
if (PrintGCDetails) {
gclog_or_tty->print_cr("GC locker: Trying a full collection "
"because scavenge failed");
}
//会执行老年代和年轻代的GC
do_collection(true /* full */,
clear_all_soft_refs /* clear_all_soft_refs */,
0 /* size */,
false /* is_tlab */,
n_gens() - 1 /* max_level */);
}
}
bool incremental_collection_will_fail(bool consult_young) {
assert(heap()->collector_policy()->is_two_generation_policy(),
"the following definition may not be suitable for an n(>2)-generation system");
return incremental_collection_failed() ||
(consult_young && !get_gen(0)->collection_attempt_is_safe());
}
//当老年代空间不足以promote,年轻代执行GC前调用collection_attempt_is_safe方法返回false,就会将_incremental_collection_failed属性置为false
bool incremental_collection_failed() const {
return _incremental_collection_failed;
}
_incremental_collection_failed属性通过set_incremental_collection_failed方法设置为true,该方法的调用链如下:
image.png都是在collection_attempt_is_safe方法返回false,即利用老年代执行promote时因为老年代内存不足可能会失败时调用的。
GCCause::_gc_locker的调用链如下:
image.png
其中只有GC_locker::jni_unlock方法不是判断GC的原因是否是_gc_locker,如下:
image.png该方法就是用于在最后一个线程从JNI关键区退出后负责触发GC。
do_full_collection方法的调用链如下:
image.png
5、collect
collect方法是对JVM外部如JNI接口使用的触发垃圾回收的方法,其调用链如下:
上述调用场景都是基于JNI接口的调用,其中JVM_GC就是System.gc()方法的底层实现,其实现如下:
image.pngcollect方法的实现如下:
void GenCollectedHeap::collect(GCCause::Cause cause) {
if (should_do_concurrent_full_gc(cause)) {
#if INCLUDE_ALL_GCS
// mostly concurrent full collection
collect_mostly_concurrent(cause);
#else // INCLUDE_ALL_GCS
ShouldNotReachHere();
#endif // INCLUDE_ALL_GCS
} else if (cause == GCCause::_wb_young_gc) {
// minor collection for WhiteBox API
collect(cause, 0);
} else {
// Stop-the-world full collection
collect(cause, n_gens() - 1);
}
}
bool GenCollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) {
//UseConcMarkSweepGC表示使用CMS GC算法
//GCLockerInvokesConcurrent的默认值为false
//ExplicitGCInvokesConcurrent的默认值也是false
return UseConcMarkSweepGC &&
((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
(cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent));
}
void GenCollectedHeap::collect_mostly_concurrent(GCCause::Cause cause) {
assert(!Heap_lock->owned_by_self(), "Should not own Heap_lock");
MutexLocker ml(Heap_lock);
// Read the GC counts while holding the Heap_lock
unsigned int full_gc_count_before = total_full_collections();
unsigned int gc_count_before = total_collections();
{
MutexUnlocker mu(Heap_lock);
//底层调用do_full_collection
VM_GenCollectFullConcurrent op(gc_count_before, full_gc_count_before, cause);
VMThread::execute(&op);
}
}
void GenCollectedHeap::collect(GCCause::Cause cause, int max_level) {
// The caller doesn't have the Heap_lock
assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
MutexLocker ml(Heap_lock);
collect_locked(cause, max_level);
}
void GenCollectedHeap::collect_locked(GCCause::Cause cause, int max_level) {
// Read the GC count while holding the Heap_lock
unsigned int gc_count_before = total_collections();
unsigned int full_gc_count_before = total_full_collections();
{
//获取Heap_lock锁
MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back
//底层还是调用do_full_collection
VM_GenCollectFull op(gc_count_before, full_gc_count_before,
cause, max_level);
VMThread::execute(&op);
}
}
6、VM_GenCollectFullConcurrent / VM_GenCollectFull
VM_GenCollectFull比较简单,就是调用do_full_collection方法;VM_GenCollectFullConcurrent要复杂点,年轻代通过do_full_collection方法执行GC,老年代通过触发CMSThread执行GC,即异步完成GC,其实现如下:
VM_GenCollectFull(uint gc_count_before,
uint full_gc_count_before,
GCCause::Cause gc_cause,
int max_level)
: VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */),
_max_level(max_level) { }
void VM_GenCollectFull::doit() {
SvcGCMarker sgcm(SvcGCMarker::FULL);
GenCollectedHeap* gch = GenCollectedHeap::heap();
GCCauseSetter gccs(gch, _gc_cause);
gch->do_full_collection(gch->must_clear_all_soft_refs(), _max_level);
}
VM_GenCollectFullConcurrent(uint gc_count_before,
uint full_gc_count_before,
GCCause::Cause gc_cause)
: VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */),
_disabled_icms(false)
{
assert(FullGCCount_lock != NULL, "Error");
assert(UseAsyncConcMarkSweepGC, "Else will hang caller");
}
//判断是否需要在安全点上执行
bool VM_GenCollectFullConcurrent::evaluate_at_safepoint() const {
Thread* thr = Thread::current();
assert(thr != NULL, "Unexpected tid");
if (!thr->is_Java_thread()) {
//如果是VMThread执行的
assert(thr->is_VM_thread(), "Expected to be evaluated by VM thread");
GenCollectedHeap* gch = GenCollectedHeap::heap();
if (_gc_count_before != gch->total_collections()) {
//如果已经完成了一次Young GC
assert(_gc_count_before < gch->total_collections(),
"total_collections() should be monotnically increasing");
return false; // no need for foreground young gc
}
}
//如果是JavaThread调用的,如System.gc()方法
return true; // may still need foreground young gc
}
void VM_GenCollectFullConcurrent::doit() {
assert(Thread::current()->is_VM_thread(), "Should be VM thread");
assert(GCLockerInvokesConcurrent || ExplicitGCInvokesConcurrent, "Unexpected");
GenCollectedHeap* gch = GenCollectedHeap::heap();
if (_gc_count_before == gch->total_collections()) {
//GC的次数没有变说明未执行young gc
assert(SafepointSynchronize::is_at_safepoint(),
"We can only be executing this arm of if at a safepoint");
GCCauseSetter gccs(gch, _gc_cause);
//执行年轻代的垃圾回收
gch->do_full_collection(gch->must_clear_all_soft_refs(),
0 /* collect only youngest gen */);
} // Else no need for a foreground young gc
assert((_gc_count_before < gch->total_collections()) || //执行过GC了
(GC_locker::is_active()
&& (_gc_count_before == gch->total_collections())), //因为有线程处于JNI关键区,GC被中止了
"total_collections() should be monotonically increasing");
//获取锁FullGCCount_lock
MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
assert(_full_gc_count_before <= gch->total_full_collections(), "Error");
if (gch->total_full_collections() == _full_gc_count_before) {
//total_full_collections未变,说明老年代的GC未执行
//禁用icms
CMSCollector::disable_icms();
_disabled_icms = true;
//唤醒在icms_wait()上等待的CMS Thread
CMSCollector::start_icms();
//推动CMS Thread执行一次老年代的GC
CMSCollector::request_full_gc(_full_gc_count_before, _gc_cause);
} else {
//说明已经执行过一次老年代GC了,不用再执行
assert(_full_gc_count_before < gch->total_full_collections(), "Error");
FullGCCount_lock->notify_all(); // Inform the Java thread its work is done
}
}
//GC结束后调用
void VM_GenCollectFullConcurrent::doit_epilogue() {
Thread* thr = Thread::current();
assert(thr->is_Java_thread(), "just checking");
JavaThread* jt = (JavaThread*)thr;
//释放锁
Heap_lock->unlock();
release_and_notify_pending_list_lock();
GenCollectedHeap* gch = GenCollectedHeap::heap();
if (_gc_cause != GCCause::_gc_locker &&
gch->total_full_collections_completed() <= _full_gc_count_before) {
//正常只有调用System.gc()时会走此方法
assert(_gc_cause == GCCause::_java_lang_system_gc,
"the only way to get here if this was a System.gc()-induced GC");
assert(ExplicitGCInvokesConcurrent, "Error");
//调整线程状态由in vm到in nativee
ThreadToNativeFromVM native(jt);
//获取锁MutexLockerEx
MutexLockerEx ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
while (gch->total_full_collections_completed() <= _full_gc_count_before) {
//还是小于等于,说明GC未完成,在FullGCCount_lock上等待直到total_full_collections_completed大于_full_gc_count_before
//即GC结束
FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag);
}
}
if (_disabled_icms) {
//重新开启icms
CMSCollector::enable_icms();
}
}
bool GenCollectedHeap::must_clear_all_soft_refs() {
return _gc_cause == GCCause::_last_ditch_collection;
}
void CMSCollector::request_full_gc(unsigned int full_gc_count, GCCause::Cause cause) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
unsigned int gc_count = gch->total_full_collections();
if (gc_count == full_gc_count) {
MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
_full_gc_requested = true;
_full_gc_cause = cause;
CGC_lock->notify(); //唤醒CMS Thread,该线程检查_full_gc_requested为true会触发一次老年代的GC
} else {
assert(gc_count > full_gc_count, "Error: causal loop");
}
}
unsigned int total_full_collections_completed() {
assert(_full_collections_completed <= _total_full_collections,
"Can't complete more collections than were started");
return _full_collections_completed;
}
上述代码中的ThreadToNativeFromVM用于将当前线程的状态从in vm调整成in native,其实现如下:
7、gen_process_roots / gen_process_weak_roots
gen_process_roots用于遍历处理ClassLoaderDataGraph,Threads,Universe等组件中包含的oop,将这些oop作为根节点遍历其所引用的其他oop,根据参数还能遍历年轻代和老年代中的所有oop,遍历脏的卡表项对应的内存区域中包含的oop。gen_process_weak_roots用于遍历JNI弱引用和Reference弱引用实例。
void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) {
//遍历JNI弱引用
JNIHandles::weak_oops_do(root_closure);
for (int i = 0; i < _n_gens; i++) {
//遍历所有的Reference实例
_gens[i]->ref_processor()->weak_oops_do(root_closure);
}
}
void GenCollectedHeap::gen_process_roots(int level,
bool younger_gens_as_roots,
bool activate_scope,
ScanningOption so,
bool only_strong_roots,
OopsInGenClosure* not_older_gens,
OopsInGenClosure* older_gens,
CLDClosure* cld_closure) {
const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots;
bool is_moving_collection = false;
if (level == 0 || is_adjust_phase) {
//is_moving_collection表示垃圾回收过程中是否会移动对象
is_moving_collection = true;
}
//is_moving_collection实际对应_fix_relocations属性,如果为true,则遍历nmethod完后,会调用
//其fix_oop_relocations方法用于让nmethod中的oop指向对象移动后的地址
MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection);
//weak_roots主要用于遍历StringTable中保存的String对象和SystemDictionary中保存的ProtectionDomain对象,这些对象如果不遍历且不被其他存活对象引用则会被回收掉
OopsInGenClosure* weak_roots = only_strong_roots ? NULL : not_older_gens;
//weak_cld_closure用来遍历keep_live属性为false的ClassLoaderData,同上,如果不遍历则会被回收掉
CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
//处理ClassLoaderDataGraph,Threads,Universe等组件中包含的oop,这些都作为根节点
process_roots(activate_scope, so,
not_older_gens, weak_roots,
cld_closure, weak_cld_closure,
&mark_code_closure);
if (younger_gens_as_roots) {
//younger_gens_as_roots为true,表示需要遍历年轻代中的所有对象,将其作为根节点
//is_task_claimed返回false表示这个任务还未执行
if (!_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) {
//因为是i小于level,所以对年轻代而言,即使younger_gens_as_roots为true,也不会执行
//只有老年代,level=1时才会进入此分支
for (int i = 0; i < level; i++) {
not_older_gens->set_generation(_gens[i]);
_gens[i]->oop_iterate(not_older_gens);
}
not_older_gens->reset_generation();
}
}
//level最低是0,即年轻代GC会调用老年代的younger_refs_iterate方法,如果level是1则不做任何处理,即老年代GC不会执行此逻辑
for (int i = level+1; i < _n_gens; i++) {
older_gens->set_generation(_gens[i]);
//younger_refs_iterate支持并行遍历,注意年轻代的该方法是一个空实现
rem_set()->younger_refs_iterate(_gens[i], older_gens);
older_gens->reset_generation();
}
//标识当前线程执行完成
_process_strong_tasks->all_tasks_completed();
}
void GenCollectedHeap::process_roots(bool activate_scope,
ScanningOption so,
OopClosure* strong_roots,
OopClosure* weak_roots,
CLDClosure* strong_cld_closure,
CLDClosure* weak_cld_closure,
CodeBlobToOopClosure* code_roots) {
//修改SharedHeap的_strong_roots_parity属性
StrongRootsScope srs(this, activate_scope);
// General roots.
assert(_strong_roots_parity != 0, "must have called prologue code");
assert(code_roots != NULL, "code root closure should always be set");
//如果这个任务还未执行
if (!_process_strong_tasks->is_task_claimed(GCH_PS_ClassLoaderDataGraph_oops_do)) {
//遍历所有的ClassLoaderData,如果ClassLoaderData的keep_alive为true则使用strong_cld_closure处理,否则使用weak_cld_closure
ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure);
}
CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL;
//so & SO_AllCodeCache为true即so等于SO_AllCodeCache或者SO_ScavengeCodeCache
CodeBlobToOopClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots;
//遍历所有JavaThread和VMThread中包含的oop,包含通过JNI创建的oop和栈上的oop
Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p);
if (!_process_strong_tasks->is_task_claimed(GCH_PS_Universe_oops_do)) {
//遍历Universe中包含的oop
Universe::oops_do(strong_roots);
}
// Global (strong) JNI handles
if (!_process_strong_tasks->is_task_claimed(GCH_PS_JNIHandles_oops_do)) {
//遍历JNI全局引用中的oop
JNIHandles::oops_do(strong_roots);
}
if (!_process_strong_tasks->is_task_claimed(GCH_PS_ObjectSynchronizer_oops_do)) {
//遍历ObjectSynchronizer即synchronize关键字的实现中包含的oop,主要是锁对象
ObjectSynchronizer::oops_do(strong_roots);
}
if (!_process_strong_tasks->is_task_claimed(GCH_PS_FlatProfiler_oops_do)) {
FlatProfiler::oops_do(strong_roots);
}
if (!_process_strong_tasks->is_task_claimed(GCH_PS_Management_oops_do)) {
//遍历MemoryService和ThreadService中的oop
Management::oops_do(strong_roots);
}
if (!_process_strong_tasks->is_task_claimed(GCH_PS_jvmti_oops_do)) {
JvmtiExport::oops_do(strong_roots);
}
if (!_process_strong_tasks->is_task_claimed(GCH_PS_SystemDictionary_oops_do)) {
//遍历SystemDictionary系统字典中的oop
SystemDictionary::roots_oops_do(strong_roots, weak_roots);
}
//所有线程都要执行一遍StringTable的oop遍历
if (weak_roots != NULL) {
if (CollectedHeap::use_parallel_gc_threads()) {
StringTable::possibly_parallel_oops_do(weak_roots);
} else {
StringTable::oops_do(weak_roots);
}
}
if (!_process_strong_tasks->is_task_claimed(GCH_PS_CodeCache_oops_do)) {
//SO_AllCodeCache是包含SO_ScavengeCodeCache的,所以如果是SO_ScavengeCodeCache
//也会执行此逻辑
if (so & SO_ScavengeCodeCache) {
assert(code_roots != NULL, "must supply closure for code cache");
//遍历nmethods
CodeCache::scavenge_root_nmethods_do(code_roots);
}
if (so & SO_AllCodeCache) {
assert(code_roots != NULL, "must supply closure for code cache");
// 遍历整个CodeBlob
CodeCache::blobs_do(code_roots);
}
}
}
void CardTableRS::younger_refs_iterate(Generation* g,
OopsInGenClosure* blk) {
_last_cur_val_in_gen[g->level()+1] = cur_youngergen_card_val();
//年轻代该方法是空实现,老年代下底层是调用CardTableRS::younger_refs_in_space_iterate方法来遍历脏的卡表项
//将脏的卡表项对应的内存区域中包含的oop作为根节点
g->younger_refs_iterate(blk);
}
StrongRootsScope用来改变SharedHeap的_strong_roots_parity属性,其实现如下:
image.png image.png其调用链如下:
image.pngCardTableRS::younger_refs_iterate方法相关实现可以参考《Hotspot 垃圾回收之BarrierSet(三) 源码解析》、《Hotspot 垃圾回收之ConcurrentMarkSweepGeneration(三) 源码解析》和《Hotspot 垃圾回收之CompactibleFreeListSpace(三) 源码解析》,整体实现比较复杂。
8、save_marks / oop_since_save_marks_iterate / no_allocs_since_save_marks
oop_since_save_marks_iterate并不是简单的调用底层Generation的oop_since_save_marks_iterate方法,而是有特殊逻辑在里面,其定义同样是通过宏实现的,如下:
void GenCollectedHeap::save_marks() {
for (int i = 0; i < _n_gens; i++) {
_gens[i]->save_marks();
}
}
#define GCH_SINCE_SAVE_MARKS_ITERATE_DEFN(OopClosureType, nv_suffix) \
void GenCollectedHeap:: \
oop_since_save_marks_iterate(int level, \
OopClosureType* cur, \
OopClosureType* older) { \
//先遍历指定level的
_gens[level]->oop_since_save_marks_iterate##nv_suffix(cur); \
//再遍历老年代,如果level本身就是1则不做处理
for (int i = level+1; i < n_gens(); i++) { \
_gens[i]->oop_since_save_marks_iterate##nv_suffix(older); \
} \
}
ALL_SINCE_SAVE_MARKS_CLOSURES(GCH_SINCE_SAVE_MARKS_ITERATE_DEFN)
//只要有一个Generation的no_allocs_since_save_marks返回false,则no_allocs_since_save_marks同样返回false
bool GenCollectedHeap::no_allocs_since_save_marks(int level) {
for (int i = level; i < _n_gens; i++) {
if (!_gens[i]->no_allocs_since_save_marks()) return false;
}
return true;
}
各方法的调用链如下:
image.png image.png即如果是年轻代调用,则会处理年轻代和老年代,如果是老年代调用,则只处理老年代。年轻代调用oop_since_save_marks_iterate是遍历saved_mark_word到top之间的对象,主要是年轻代并行遍历和老年代通过CMSThread遍历时使用,如果是单线程的年轻代遍历则不做任何处理,因为此时saved_mark_word就是top,老年代是遍历所有被promoted的对象。
9、ensure_parsability
GenCollectedHeap改写了父类的实现,在父类的基础上增加了各各Generation的ensure_parsability方法的调用,但是CMS下年轻代和老年代都是空实现,父类方法的实现可以参考BarrierSet(三。
void GenCollectedHeap::ensure_parsability(bool retire_tlabs) {
//调用父类实现,父类实现会遍历所有的JavaThread,让其TLAB被填充或者退休,不再用于分配对象,同时将上一次本地代码创建的对象对应的卡表项置为脏的
CollectedHeap::ensure_parsability(retire_tlabs);
//调用各Generation的ensure_parsability方法,CMS下年轻代和老年代都是空实现
GenEnsureParsabilityClosure ep_cl;
generation_iterate(&ep_cl, false);
}
class GenEnsureParsabilityClosure: public GenCollectedHeap::GenClosure {
public:
void do_generation(Generation* gen) {
gen->ensure_parsability();
}
};
网友评论