简单说,偏向锁 在 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。简单地说,偏向锁只有在单个线程里使用老的容器类,如 Vector
、Hashtable
时,才会发挥他的作用。而新一点的代码,基本使用的是 ArrayList
、HashMap
,此时偏向锁根本没什么用,反而让虚拟机的实现变得复杂,还拖慢了一点执行速度。
但是,在 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 则直接移除了(普大喜奔🎉🎉)。
网友评论