美文网首页
hotspot 的偏向锁被干掉了?

hotspot 的偏向锁被干掉了?

作者: 虾饺的开发手记 | 来源:发表于2023-04-24 23:51 被阅读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 则直接移除了(普大喜奔🎉🎉)。

相关文章

  • JVM同步方法之偏向锁

    其实很早之前通过一些资料,就对偏向锁稍微有些了解,周六准备看看Hotspot中关于偏向锁的实现,本以为应该畅通无阻...

  • HotSpot 偏向锁,原始论文翻译

    论文:Eliminating Synchronization-Related Atomic Operations ...

  • 偏向锁、轻量级锁、重量级锁、自旋锁、自适应自旋锁

    1. 偏向锁 偏向锁就是在运行过程中,对象的锁偏向某个线程。即在开启偏向锁机制的情况下,某个线程获得锁,当该线程下...

  • 偏向锁、轻量级锁、重量级锁、自旋锁、自适应自旋锁

    1. 偏向锁 偏向锁就是在运行过程中,对象的锁偏向某个线程。即在开启偏向锁机制的情况下,某个线程获得锁,当该线程下...

  • 锁 - 偏向锁、轻量级锁、重量级锁及锁优化

    偏向锁 轻量级锁 重量级锁 锁的状态总共有四种:无锁状态、偏向锁、轻量级锁和重量级锁。 随着锁的竞争,锁可以从偏向...

  • 偏向锁

    HopSpot的作者经过研究发现,大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得...

  • 偏向锁

    定义 大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低引入了偏向锁。 ...

  • Java虚拟机的锁优化

    JDK内部的优化策略主要包括以下几点 锁偏向 轻量级锁 自旋锁 锁消除 1.锁偏向 锁偏向是一种针对加锁操作的优化...

  • Concurrency-锁升级

    concurrency-锁升级 4种锁状态: 无锁 偏向锁 轻量级锁 重量级锁 无锁 jvm会有4秒的偏向锁开启的...

  • synchronized锁升级详解

    锁升级的顺序:偏向锁 -> 轻量级锁 ->重量级锁 偏向锁:1、使用了synchronized关键字的代码,如果没...

网友评论

      本文标题:hotspot 的偏向锁被干掉了?

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