OpenJDK16 ZGC 源码分析(五)GC阶段之并发标记

1. 简介

并发标记是ZGC的第2个阶段,此阶段中,GC worker与Mutator并发工作,GC worker执行标记、load barrier和relocate。

并发线程从带标记对象列表开始,递归遍历对象及对象的成员变量并标记。

2. 源码分析

2.1 入栈

标记栈的size受ZMarkStackSpaceLimit参数控制,默认8G,合法值32MB到1TB之间。
share/gc/z/z_globals.hpp

  product(size_t, ZMarkStackSpaceLimit, 8*G,                               
          "Maximum number of bytes allocated for mark stacks")             
          range(32*M, 1024*G)                                              

标记栈元素分为两种:

  • 如果是普通对象,则直接入栈、递归标记即可。
  • 如果是数组对象,全部入栈则可能引起溢出,需判断数组大小是否超过ZMarkPartialArrayMinSize(默认4KB),未超过则入栈标记,否则按ZMarkPartialArrayMinSize切分后入栈标记。
    share/gc/z/zMarkStackEntry.hpp
  ZMarkStackEntry(uintptr_t object_address, bool follow, bool finalizable) :
      _entry(field_object_address::encode(object_address) |
             field_follow::encode(follow) |
             field_partial_array::encode(false) |
             field_finalizable::encode(finalizable)) {
   }

  ZMarkStackEntry(size_t partial_array_offset, size_t partial_array_length, bool finalizable) :
      _entry(field_partial_array_offset::encode(partial_array_offset) |
             field_partial_array_length::encode(partial_array_length) |
             field_partial_array::encode(true) |
             field_finalizable::encode(finalizable)) {
   }

share/gc/z/zMark.cpp

void ZMark::push_partial_array(uintptr_t addr, size_t size, bool finalizable) {
   
  assert(is_aligned(addr, ZMarkPartialArrayMinSize), "Address misaligned");
  ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(Thread::current());
  ZMarkStripe* const stripe = _stripes.stripe_for_addr(addr);
  const uintptr_t offset = ZAddress::offset(addr) >> ZMarkPartialArrayMinSizeShift;
  const uintptr_t length = size 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值