Repository navigation
g1 mark Meta_Space_GC
ceragon edited this page Dec 18, 2021
·
1 revision
- 在元空间的收集时,也会触发到 GC 的逻辑中。下面是调用的方法
bool VM_CollectForMetadataAllocation::initiate_concurrent_GC() {
// 是否 G1 GC,另一个参数的默认值是 true
if (UseG1GC && ClassUnloadingWithConcurrentMark) {
// 是否应该启动标记循环
bool should_start = g1h->g1_policy()->force_initial_mark_if_outside_cycle(_gc_cause);
if (should_start) {
g1h->do_collection_pause_at_safepoint(pause_target);
}
return true;
}
}- 调用 initiate_concurrent_GC() 的类和方法如下:
class VM_CollectForMetadataAllocation: public VM_GC_Operation: public VM_Operation {
// 所有继承自 VM_Operation 的类都是在 VM Thread 中执行
// 该类的对象一旦被 VM Thread 开始执行,会先申请 STW
// 等 STW 成功后,会执行 doit() 方法
}
void VM_CollectForMetadataAllocation::doit() {
// 该参数默认是 false
if (!MetadataAllocationFailALot) {
// 默认情况下,会进入到该方法
// 可以理解为尝试在元空间分配空间,分配成功返回 true
_result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
if (_result != NULL) {
// 分配成功
return;
}
}
// 调用目标方法
if (initiate_concurrent_GC()) {
}
}- 调用上面那个类构造方法的位置如下
MetaWord* CollectedHeap::satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
size_t word_size,
Metaspace::MetadataType mdtype) {
// 在元空间分配空间
MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
if (result != NULL) {
// 分配成功
return result;
}
// 分配空间失败,被迫走 GC 流程
VM_CollectForMetadataAllocation op(loader_data,
word_size,
mdtype,
gc_count,
full_gc_count,
GCCause::_metadata_GC_threshold);
VMThread::execute(&op);
}