概述
本系列文章采用的源码是来自JDK17.0.5;
zgc初始化流程
JVM在进程启动时会通过Universe::initialize_heap来创建堆对象:
jint Universe::initialize_heap() {
_collectedHeap = GCConfig::arguments()->create_heap();
return _collectedHeap->initialize();
}
CollectedHeap* ZArguments::create_heap() {
return new ZCollectedHeap();
}
ZCollectedHeap::ZCollectedHeap() :
_soft_ref_policy(),
_barrier_set(),
_initialize(&_barrier_set),
_heap(),
_driver(new ZDriver()),
_director(new ZDirector(_driver)),
_stat(new ZStat()),
_runtime_workers() {}
此处的new ZDriver()和new ZDirector会分别启动ZDriver和ZDirector线程;
ZDirector线程
ZDriver类继承自ConcurrentGCThread,其run方法如下:
void ZDirector::run_service() {
// Main loop
while (_metronome.wait_for_tick()) {
sample_allocation_rate();
if (!_driver->is_busy()) {
const ZDriverRequest request = make_gc_decision();
if (request.cause() != GCCause::_no_gc) {
_driver->collect(request);
}
}
}
}
可以看到ZDirector线程会间隔100ms执行内存分配速率的采样,同时会判断是否需要进行GC,如果需要执行GC,则通知ZDriver线程开始进行垃圾回收;那么哪些原因会导致JVM需要进行垃圾回收呢:
static ZDriverRequest make_gc_decision() {
// List of rules
using ZDirectorRule = ZDriverRequest (*)();
const ZDirectorRule rules[] = {
rule_allocation_stall,//出现内存分配失败时
rule_warmup,//内存使用占比达到10%、20%和30%时触发
rule_timer,//默认关闭,每ZCollectionInterval秒触发一次
rule_allocation_rate,//内存分配过快触发
rule_high_usage,//可用内存小于或等于5%触发
rule_proactive,//通过ZProactive配置项控制,如果5分钟内内存占用增加10%以上才可能触发
};
ZDriver线程
ZDriver类继承自ConcurrentGCThread,其run方法如下:
void ZDriver::run_service() {
// Main loop
while (!should_terminate()) {
// Wait for GC request
const ZDriverRequest request = _gc_cycle_port.receive();
if (request.cause() == GCCause::_no_gc) {
continue;
}
ZBreakpoint::at_before_gc();
// Run GC
gc(request);
// Notify GC completed
_gc_cycle_port.ack();
// Check for out of memory condition
check_out_of_memory();
ZBreakpoint::at_after_gc();
}
}