hotspot 的偏向锁被干掉了?

2023-04-24  本文已影响0人  虾饺的开发手记

简单说,偏向锁 在 jdk15 被设置为 deprecated,17 obsolete,19 则直接移除了;因为对于大部分程序,他并没有很好地起到原先设想的作用。

至于详情,且听我慢慢道来。

怎么发现 hotspot 偏向锁被干掉的?

在看周志明的《深入理解 Java 虚拟机》时,2.3.1 对象的创建一节贴了一段 bytecode interpreter 创建对象的代码,中间有初始化偏向锁相关的对象头的代码。

但是,在 jdk17 的代码却用断言声称不应该使用偏向锁:

// jdk17/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp
template<bool JVMTI_ENABLED>
void BytecodeInterpreter::run(interpreterState istate) {
  ......

      CASE(_new): {
        u2 index = Bytes::get_Java_u2(pc+1);

        // Attempt TLAB allocation first.
        //
        // To do this, we need to make sure:
        //   - klass is initialized
        //   - klass can be fastpath allocated (e.g. does not have finalizer)
        //   - TLAB accepts the allocation
        ConstantPool* constants = istate->method()->constants();
        if (UseTLAB && !constants->tag_at(index).is_unresolved_klass()) {
          Klass* entry = constants->resolved_klass_at(index);
          InstanceKlass* ik = InstanceKlass::cast(entry);
          if (ik->is_initialized() && ik->can_be_fastpath_allocated()) {
            size_t obj_size = ik->size_helper();
            HeapWord* result = THREAD->tlab().allocate(obj_size);
            if (result != NULL) {
              // Initialize object field block:
              //   - if TLAB is pre-zeroed, we can skip this path
              //   - in debug mode, ThreadLocalAllocBuffer::allocate mangles
              //     this area, and we still need to initialize it
              if (DEBUG_ONLY(true ||) !ZeroTLAB) {
                size_t hdr_size = oopDesc::header_size();
                Copy::fill_to_words(result + hdr_size, obj_size - hdr_size, 0);
              }

              oop obj = cast_to_oop(result);

              // Initialize header
              assert(!UseBiasedLocking, "Not implemented");
              obj->set_mark(markWord::prototype());
              obj->set_klass_gap(0);
              obj->set_klass(ik);

              // Must prevent reordering of stores for object initialization
              // with stores that publish the new object.
              OrderAccess::storestore();
              SET_STACK_OBJECT(obj, 0);
              UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);
            }
          }
        }
        // Slow case allocation
        CALL_VM(InterpreterRuntime::_new(THREAD, METHOD->constants(), index),
                handle_exception);
        // Must prevent reordering of stores for object initialization
        // with stores that publish the new object.
        OrderAccess::storestore();
        SET_STACK_OBJECT(THREAD->vm_result(), 0);
        THREAD->set_vm_result(NULL);
        UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);
      }

    ......
}

注意,里面有这么一句 assert(!UseBiasedLocking, "Not implemented")

难道说,偏向锁在 java17 被干掉了?

jdk17 真的把偏向锁干掉了?

用搜索引擎简单搜索一下,可以发现这篇 JEP。简单地说,偏向锁只有在单个线程里使用老的容器类,如 VectorHashtable 时,才会发挥他的作用。而新一点的代码,基本使用的是 ArrayListHashMap,此时偏向锁根本没什么用,反而让虚拟机的实现变得复杂,还拖慢了一点执行速度。

但是,在 jdk17 的代码里全局搜索 UseBiasedLocking,可以发现除了 bytecodeInterpreter 外,其他地方又都正常实现了 UseBiasedLocking。这又是怎么回事呢?

继续扒代码,又发现 arguments.cpp 里面有这么一个参数配置:

// jdk17/src/hotspot/share/runtime/arguments.cpp

static SpecialFlag const special_jvm_flags[] = {
  ...
    { "UseBiasedLocking", JDK_Version::jdk(15), JDK_Version::jdk(18), JDK_Version::jdk(19) },
  ...
}

// Obsolete or deprecated -XX flag.
struct SpecialFlag {
  const char* name;
  JDK_Version deprecated_in; // When the deprecation warning started (or "undefined").
  JDK_Version obsolete_in;   // When the obsolete warning started (or "undefined").
  JDK_Version expired_in;    // When the option expires (or "undefined").
}; 

可以看到,UseBiasedLocking 在 jdk15 被设置为 deprecated,17 obsolete,19 则直接移除了(普大喜奔🎉🎉)。

上一篇 下一篇

猜你喜欢

热点阅读