1. 简介
ZGC最后一个阶段就是并发转移,在之前的阶段已经标记出了活跃对象和需要转移的page。因此并发转移阶段,GC并发的将转移集中的活跃对象迁移到新页面,并在转移完成后回收旧页面。
2. 源码分析
2.1 入口
并发转移的转移的入口也在zHeap。
hotspot/share/gc/z/zHeap.cpp
void ZHeap::relocate() {
// Relocate relocation set
_relocate.relocate(&_relocation_set);
// Update statistics
ZStatHeap::set_at_relocate_end(_page_allocator.stats());
}
跳转到zRelocate.cpp后,并发执行ZRelocateTask。
hotspot/share/gc/z/zRelocate.cpp
void ZRelocate::relocate(ZRelocationSet* relocation_set) {
ZRelocateTask task(relocation_set);
_workers->run_concurrent(&task);
}
2.2 并发转移Task
并发转移任务的主要逻辑如下:
class ZRelocateTask : public ZTask {
private:
ZRelocationSetParallelIterator _iter;
ZRelocateSmallAllocator _small_allocator;
ZRelocateMediumAllocator _medium_allocator;
// 判断small page还是medium page
static bool is_small(ZForwarding* forwarding) {
return forwarding->type() == ZPageTypeSmall;
}
public:
ZRelocateTask(ZRelocationSet* relocation_set) :
ZTask("ZRelocateTask"),
_iter(relocation_set),
_small_allocator(),
_medium_allocator() {
}
~ZRelocateTask() {
ZStatRelocation::set_at_relocate_end(_small_allocator.in_place_count(),
_medium_allocator.in_place_count());
}
virtual void work()