美文网首页
源码解析-触发批量撤销或批量重偏向的条件

源码解析-触发批量撤销或批量重偏向的条件

作者: M_lear | 来源:发表于2020-05-26 21:45 被阅读0次

    JVM 基于一种启发式的做法判断是否应该触发批量撤销或批量重偏向。

    依赖三个阈值作出判断:

    # 批量重偏向阈值
    -XX:BiasedLockingBulkRebiasThreshold=20
    # 重置计数的延迟时间
    -XX:BiasedLockingDecayTime=25000
    # 批量撤销阈值
    -XX:BiasedLockingBulkRevokeThreshold=40
    

    启发式的判断源码如下:

    static HeuristicsResult update_heuristics(oop o, bool allow_rebias) {
      markOop mark = o->mark();
      // 如果不是偏向模式直接返回
      if (!mark->has_bias_pattern()) {
        return HR_NOT_BIASED;
      }
     
      // 获取锁对象的类元数据
      Klass* k = o->klass();
      // 当前时间
      jlong cur_time = os::javaTimeMillis();
      // 该类上一次批量重偏向的时间
      jlong last_bulk_revocation_time = k->last_biased_lock_bulk_revocation_time();
      // 该类单个偏向撤销的计数
      int revocation_count = k->biased_lock_revocation_count();
    
      // 按默认参数来说:
      // 如果撤销计数大于等于 20,且小于 40,
      // 且距上次批量撤销的时间大于等于 25 秒,就会重置计数。
      if ((revocation_count >= BiasedLockingBulkRebiasThreshold) &&
          (revocation_count <  BiasedLockingBulkRevokeThreshold) &&
          (last_bulk_revocation_time != 0) &&
          (cur_time - last_bulk_revocation_time >= BiasedLockingDecayTime)) {
        // This is the first revocation we've seen in a while of an
        // object of this type since the last time we performed a bulk
        // rebiasing operation. The application is allocating objects in
        // bulk which are biased toward a thread and then handing them
        // off to another thread. We can cope with this allocation
        // pattern via the bulk rebiasing mechanism so we reset the
        // klass's revocation count rather than allow it to increase
        // monotonically. If we see the need to perform another bulk
        // rebias operation later, we will, and if subsequently we see
        // many more revocation operations in a short period of time we
        // will completely disable biasing for this type.
        k->set_biased_lock_revocation_count(0);
        revocation_count = 0;
      }
    
      if (revocation_count <= BiasedLockingBulkRevokeThreshold) {
        // 自增计数
        revocation_count = k->atomic_incr_biased_lock_revocation_count();
      }
      // 此时,如果达到批量撤销阈值,则进行批量撤销。
      if (revocation_count == BiasedLockingBulkRevokeThreshold) {
        return HR_BULK_REVOKE;
      }
      // 此时,如果达到批量重偏向阈值,则进行批量重偏向。
      if (revocation_count == BiasedLockingBulkRebiasThreshold) {
        return HR_BULK_REBIAS;
      }
      // 否则,仅进行单个对象的撤销偏向
      return HR_SINGLE_REVOKE;
    }
    

    简单总结,对于一个类,按默认参数来说:
    单个偏向撤销的计数达到 20,就会进行批量重偏向。
    距上次批量重偏向 25 秒内,计数达到 40,就会发生批量撤销。

    每隔 (>=) 25 秒,会重置在 [20, 40) 内的计数,这意味着可以发生多次批量重偏向。

    注意:对于一个类来说,批量撤销只能发生一次,因为批量撤销后,该类禁用了可偏向属性,后面该类的对象都是不可偏向的,包括新创建的对象。

    源码链接:http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/9ce27f0a4683/src/share/vm/runtime/biasedLocking.cpp#l268

    相关文章

      网友评论

          本文标题:源码解析-触发批量撤销或批量重偏向的条件

          本文链接:https://www.haomeiwen.com/subject/xdamahtx.html