目录
1、FastHashCode / identity_hash_value_for
4、omAlloc / omRelease / omFlush
5、InduceScavenge / deflate_idle_monitors / deflate_monitor / walk_monitor_list
java.lang.Object中一共有五个本地方法,包括hashCode,wait,notify,notifyAll和clone,ObjectSynchronizer就是前4个本地方法的底层实现,本篇博客就详细讲解Object的这5个本地方法的实现。
一、Object.c
java.lang.Object中的本地方法实现都在jdk\src\share\native\java\lang\Object.c中,其中负责定义native方法与底层C方法的对应关系的JNINativeMethod的定义如下图:
前4个方法的实现如下:
JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))
JVMWrapper("JVM_IHashCode");
//resolve_non_null方法解析出对应的oop
return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ;
JVM_END
JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms))
JVMWrapper("JVM_MonitorWait");
Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
JavaThreadInObjectWaitState jtiows(thread, ms != 0);
if (JvmtiExport::should_post_monitor_wait()) {
//发布JVMTI事件
JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms);
}
ObjectSynchronizer::wait(obj, ms, CHECK);
JVM_END
JVM_ENTRY(void, JVM_MonitorNotify(JNIEnv* env, jobject handle))
JVMWrapper("JVM_MonitorNotify");
Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
ObjectSynchronizer::notify(obj, CHECK);
JVM_END
JVM_ENTRY(void, JVM_MonitorNotifyAll(JNIEnv* env, jobject handle))
JVMWrapper("JVM_MonitorNotifyAll");
Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
ObjectSynchronizer::notifyall(obj, CHECK);
JVM_END
#define JVM_ENTRY(result_type, header) \
extern "C" { \
result_type JNICALL header { \
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
//负责切换线程状态,并检查安全点
ThreadInVMfromNative __tiv(thread); \
debug_only(VMNativeEntryWrapper __vew;) \
VM_ENTRY_BASE(result_type, header, thread)
#define VM_ENTRY_BASE(result_type, header, thread) \
TRACE_CALL(result_type, header) \
//负责在方法执行完成后恢复原来的HandleMark,即释放方法执行期间临时分配的Handle
HandleMarkCleaner __hm(thread); \
Thread* THREAD = thread; \
os::verify_stack_alignment(); \
二、JVM_Clone
JVM_Clone方法的实现如下,其对象复制的核心就是将对象的数据转换成jlong数组,然后原子的复制数组内容,因此JVM_Clone的实现就是所谓的浅拷贝。
JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
JVMWrapper("JVM_Clone");
//获取待复制的对象oop
Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
//获取待复制的对象的klass
const KlassHandle klass (THREAD, obj->klass());
JvmtiVMObjectAllocEventCollector oam;
//判断这个类是否可以clone,数组对象默认都是可以clone的
if (!klass->is_cloneable()) {
ResourceMark rm(THREAD);
//如果不可以clone,抛出异常
THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
}
// Make shallow object copy
ReferenceType ref_type = REF_NONE;
const int size = obj->size();
oop new_obj_oop = NULL;
if (obj->is_array()) {
//如果是数组
const int length = ((arrayOop)obj())->length();
//分配一个新的对象数组
new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
} else {
ref_type = InstanceKlass::cast(klass())->reference_type();
//两个条件要么都为true,要么都为false,即要么是普通Java对象,要么是Reference及其子类
assert((ref_type == REF_NONE) ==
!klass->is_subclass_of(SystemDictionary::Reference_klass()),
"invariant");
//分配一个新的对象
new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
}
assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned");
//原子的复制对象数据,底层是使用汇编指令fildll,fistpll实现的,因为此时其他某个线程可能在修改对象属性
//转换成jlong数组复制是为了保证32位系统下也能够原子的复制8字节的数据,32位系统下一次最多复制4字节数据
Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj_oop,
(size_t)align_object_size(size) / HeapWordsPerLong);
//设置对象头
new_obj_oop->init_mark();
BarrierSet* bs = Universe::heap()->barrier_set();
assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
//将卡表对应的区域标记为脏的
bs->write_region(MemRegion((HeapWord*)new_obj_oop, size));
if (ref_type != REF_NONE) {
//如果是Reference及其子类则对其相关属性做特殊处理
fixup_cloned_reference(ref_type, obj(), new_obj_oop);
}
Handle new_obj(THREAD, new_obj_oop);
//如果clone对象是java_lang_invoke_MemberName实例,该类只能在invoke包类访问
if (java_lang_invoke_MemberName::is_instance(new_obj()) &&
java_lang_invoke_MemberName::is_method(new_obj())) {
Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(new_obj());
// MemberName may be unresolved, so doesn't need registration until resolved.
if (method != NULL) {
methodHandle m(THREAD, method);
m->method_holder()->add_member_name(new_obj(), false);
}
}
if (klass->has_finalizer()) {
//如果该类改写了Object的finalize方法
assert(obj->is_instance(), "should be instanceOop");
//给该实例分配一个关联的Finalizer实例,register_finalizer方法返回的实际上还是new_obj,底层调用的Finalizer.register方法是void
new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL);
new_obj = Handle(THREAD, new_obj_oop);
}
//返回一个本地JNI引用
return JNIHandles::make_local(env, new_obj());
JVM_END
bool Klass::is_cloneable() const {
return _access_flags.is_cloneable() ||//数组类klass和实现java.lang.Cloneable接口的普通Java类的_access_flags会被标记成clone
is_subtype_of(SystemDictionary::Cloneable_klass()); //只适用于Reference及其子类
}
static void fixup_cloned_reference(ReferenceType ref_type, oop src, oop clone) {
#if INCLUDE_ALL_GCS
if (UseG1GC) {
oop referent = java_lang_ref_Reference::referent(clone);
if (referent != NULL) {
//如果是G1算法需要将非空的referent入队
G1SATBCardTableModRefBS::enqueue(referent);
}
}
#endif // INCLUDE_ALL_GCS
if ((java_lang_ref_Reference::next(clone) != NULL) ||
(java_lang_ref_Reference::queue(clone) == java_lang_ref_ReferenceQueue::ENQUEUED_queue())) {
// 如果clone属于非激活状态,将其queue置为ReferenceQueue.NULL,因为当前复制的实例实际未加入到ReferenceQueue中
java_lang_ref_Reference::set_queue(clone, java_lang_ref_ReferenceQueue::NULL_queue());
}
//将discovered和next属性置为NULL
java_lang_ref_Reference::set_discovered(clone, NULL);
java_lang_ref_Reference::set_next(clone, NULL);
}
与Klass::is_cloneable()方法对应的Klass::set_is_cloneable()方法的实现如下:
如果是Reference类及其子类则进入if分支,普通的非Reference类的ReferenceType都是REF_NONE,其他的都进入else分支,该方法的调用链如下:
ArrayKlass 是直接调用,没有条件判断,即所有的数组类都默认是可以clone的,ClassFileParser调用时有条件,如下图:
Cloneable_klass_loaded方法判断java.lang.Clonable这个接口klass是否已加载,这个是在JVM启动时加载的;is_subtype_of判断是否实现了Clonable接口,如果实现了则在_access_flags中打标,该Klass支持Clone。
三、浅拷贝与深拷贝
浅拷贝是指对象复制时只复制属性本身,深拷贝在浅拷贝的基础上还会复制引用类型属性所指向的对象,让对应的引用类型属性指向新的对象。测试用例如下:
package jni;
import org.junit.Test;
class TestA implements Cloneable {
@Override
public TestA clone() throws CloneNotSupportedException {
return (TestA)super.clone();
}
}
class TestB implements Cloneable {
@Override
public TestB clone() throws CloneNotSupportedException {
return (TestB)super.clone();
}
}
class TestC implements Cloneable{
public TestA testA;
public TestB testB;
public TestC(TestA testA, TestB testB) {
this.testA = testA;
this.testB = testB;
}
@Override
public TestC clone() throws CloneNotSupportedException {
//使用Object的默认实现
return (TestC) super.clone();
}
}
class TestD implements Cloneable{
public TestA testA;
public TestB testB;
public TestD(TestA testA, TestB testB) {
this.testA = testA;
this.testB = testB;
}
@Override
public TestD clone() throws CloneNotSupportedException {
//使用Object的默认实现复制非引用类型属性
TestD testD= (TestD) super.clone();
//分别拷贝两个引用类型属性
testD.testA=testA.clone();
testD.testB=testB.clone();
return testD;
}
}
public class CloneTest {
@Test
public void test() throws Exception {
TestA a=new TestA();
TestB b=new TestB();
TestC c=new TestC(a,b);
TestC c2=c.clone();
//浅拷贝测试,c2是一个新的TestC对象,所以返回false
System.out.println(c2==c);
//c2的引用类型属性和c的一样,所以下面两个都返回true
System.out.println(c2.testA==c.testA);
System.out.println(c2.testB==c.testB);
}
@Test
public void test2() throws Exception {
TestA a=new TestA();
TestB b=new TestB();
TestD c=new TestD(a,b);
TestD c2=c.clone();
//深拷贝,都指向不同的对象,三个都返回false
System.out.println(c2==c);
System.out.println(c2.testA==c.testA);
System.out.println(c2.testB==c.testB);
}
}
上述深拷贝的实现要求每一个引用类型属性对应类都得改写Object的clone方法,如果这些类的父类包含私有的引用类型属性,还需要父类改写Object的clone方法来处理这些私有的引用类型属性,比较麻烦,可以通过以下两种方式来实现深拷贝:
@Test
public void test3() throws Exception {
TestA a=new TestA();
TestB b=new TestB();
TestC c=new TestC(a,b);
TestC c2=null;
try(PipedOutputStream out=new PipedOutputStream();
PipedInputStream in=new PipedInputStream(out);
ObjectOutputStream bo=new ObjectOutputStream(out);
ObjectInputStream bi=new ObjectInputStream(in)) {
//利用对象序列化的方式实现,要求所有类实现Serializable接口
bo.writeObject(c);
c2=(TestC) bi.readObject();
} catch (Exception e) {
e.printStackTrace();
}
//都指向新的对象,返回false
System.out.println(c2==c);
System.out.println(c2.testA==c.testA);
System.out.println(c2.testB==c.testB);
}
@Test
public void test4() throws Exception {
TestA a=new TestA();
TestB b=new TestB();
TestC c=new TestC(a,b);
//利用JSON序列化的方式实现深拷贝
String str= JSON.toJSONString(c);
TestC c2=JSON.parseObject(str,TestC.class);
//都指向新的对象,返回false
System.out.println(c2==c);
System.out.println(c2.testA==c.testA);
System.out.println(c2.testB==c.testB);
}
对象序列化和JSON序列化都有很多不同的开源实现,出了这两种以外,还有一种,通过反射的方式,遍历所有的属性,如果是基本类型则直接复制值即可,如果是引用类型属性,则获取引用的类,通过反射new一个类出来,以同样的方式处理这个new出来的类的属性,这种性能损耗比较大,也比较复杂,不如直接使用对象序列化的方式,JSON序列化不适用于复杂嵌套结构的类。
四、ObjectSynchronizer
ObjectSynchronizer的定义位于hotspot\src\share\vm\runtime\synchronizer.hpp中,其包含的属性如下:
- static ObjectMonitor* gBlockList; //全局的所有ObjectMonitor数组的链表,每个元素都是一个ObjectMonitor数组的头元素,可以据此遍历所有的ObjectMonitor实例
- static ObjectMonitor * volatile gFreeList; //全局的空闲ObjectMonitor链表
- static ObjectMonitor * volatile gOmInUseList; //全局的正在使用的ObjectMonitor链表,只有MonitorInUseLists为true时才有值
- static int gOmInUseCount; //gOmInUseList中包含的元素个数
- static volatile intptr_t ListLock = 0 ; // 操作gFreeList的锁
- static volatile int MonitorFreeCount = 0 ; //gFreeList中包含的元素的个数
- static volatile int MonitorPopulation = 0 ; // 已经创建的ObjectMonitor的总数
该类用于实现Object的wait / notify方法,synchronized关键字底层的monitorenter / monitorexit字节码指令,JNI中用于获取锁的接口jni_MonitorEnter / jni_MonitorExit,Unsafe类的Unsafe_MonitorEnter / Unsafe_MonitorExit方法,相关方法会陆续的介绍,本篇博客重点介绍跟Object本地方法实现相关的几个方法。
1、FastHashCode / identity_hash_value_for
FastHashCode是Object类的hashCode方法和System类的identityHashCode方法的底层实现,identity_hash_value_for方法是JVM内部使用的获取某个oop的hash码,用于获取匿名类的类名或者将某个oop放入Map时据此计算key,该方法也是基于FastHashCode实现的。FastHashCode的调用链如下:
其实现如下:
intptr_t ObjectSynchronizer::identity_hash_value_for(Handle obj) {
return FastHashCode (Thread::current(), obj()) ;
}
intptr_t ObjectSynchronizer::FastHashCode (Thread * Self, oop obj) {
//UseBiasedLocking表示是否启用偏向锁
if (UseBiasedLocking) {
if (obj->mark()->has_bias_pattern()) {
// Box and unbox the raw reference just in case we cause a STW safepoint.
Handle hobj (Self, obj) ;
// Relaxing assertion for bug 6320749.
assert (Universe::verify_in_progress() ||
!SafepointSynchronize::is_at_safepoint(),
"biases should not be seen by VM thread here");
//撤销偏向锁
BiasedLocking::revoke_and_rebias(hobj, false, JavaThread::current());
obj = hobj() ;
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
}
// hashCode() is a heap mutator ...
// Relaxing assertion for bug 6320749.
assert (Universe::verify_in_progress() ||
!SafepointSynchronize::is_at_safepoint(), "invariant") ;
assert (Universe::verify_in_progress() ||
Self->is_Java_thread() , "invariant") ;
assert (Universe::verify_in_progress() ||
((JavaThread *)Self)->thread_state() != _thread_blocked, "invariant") ;
ObjectMonitor* monitor = NULL;
markOop temp, test;
intptr_t hash;
//如果该对象处于锁膨胀的过程中则通过自旋或者阻塞的方式等待锁膨胀完成
markOop mark = ReadStableMark (obj);
// object should remain ineligible for biased locking
assert (!mark->has_bias_pattern(), "invariant") ;
if (mark->is_neutral()) {
//如果该对象没有持有锁
hash = mark->hash(); // this is a normal header
if (hash) { // if it has hash, just return it
//如果对象头中保存有hash码则直接返回从对象头中获取的hash码
return hash;
}
//对象头中没有hash码,计算一个新的hash码
hash = get_next_hash(Self, obj); // allocate a new hash code
//将hash码保存到对象头中
temp = mark->copy_set_hash(hash); // merge the hash code into header
//原子的重置对象头
test = (markOop) Atomic::cmpxchg_ptr(temp, obj->mark_addr(), mark);
if (test == mark) {
//重置成功
return hash;
}
//重置失败,有其他线程修改了该对象的兑现头
} else if (mark->has_monitor()) {
//如果持有监视器锁即重量级锁,从对象头中获取监视器的指针
monitor = mark->monitor();
//获取ObjectMonitor保存的对象原来的对象头
temp = monitor->header();
assert (temp->is_neutral(), "invariant") ;
hash = temp->hash();
if (hash) {
//如果对象头中有hash码,则直接返回
return hash;
}
// 对象头中无hash码
} else if (Self->is_lock_owned((address)mark->locker())) {
//如果持有轻量级锁,去掉对象头中的锁表示,此时对象头包含的指针是指向线程栈的某个地址
//该地址保存了该对象原来的对象头,displaced_mark_helper就是获取原来的对象头
temp = mark->displaced_mark_helper(); // this is a lightweight monitor owned
assert (temp->is_neutral(), "invariant") ;
hash = temp->hash(); // by current thread, check if the displaced
if (hash) { // header contains hash code
return hash;
}
}
//进行锁膨胀,获取该对象关联的ObjectMonitor
monitor = ObjectSynchronizer::inflate(Self, obj);
//获取该对象的对象头
mark = monitor->header();
assert (mark->is_neutral(), "invariant") ;
hash = mark->hash();
if (hash == 0) {
//如果没有hash码则生成一个
hash = get_next_hash(Self, obj);
//保存hash码
temp = mark->copy_set_hash(hash); // merge hash code into header
assert (temp->is_neutral(), "invariant") ;
test = (markOop) Atomic::cmpxchg_ptr(temp, monitor, mark);
if (test != mark) {
//如果原子的更新失败,则返回原来的hash码
hash = test->hash();
assert (test->is_neutral(), "invariant") ;
assert (hash != 0, "Trivial unexpected object/monitor header usage.");
}
}
// We finally get the hash
return hash;
}
static markOop ReadStableMark (oop obj) {
markOop mark = obj->mark() ;
if (!mark->is_being_inflated()) {
//如果没有处于锁膨胀的过程中,则直接返回,锁膨胀是一个非常短暂的中间状态
return mark ; // normal fast-path return
}
int its = 0 ;
//相当于while(true)死循环
for (;;) {
markOop mark = obj->mark() ;
if (!mark->is_being_inflated()) {
//如果没有处于锁膨胀的过程中,则直接返回
return mark ; // normal fast-path return
}
//如果该对象处于锁膨胀的过程中,则调用方必须等待锁膨胀完成
++its ;
if (its > 10000 || !os::is_MP()) {
//循环超过1000此或者是单核系统
if (its & 1) {
//如果是奇数次循环,让当前线程yeild
os::NakedYield() ;
TEVENT (Inflate: INFLATING - yield) ;
} else {
//根据对象地址算出用于表示膨胀锁的指针数组的索引
int ix = (cast_from_oop<intptr_t>(obj) >> 5) & (NINFLATIONLOCKS-1) ;
int YieldThenBlock = 0 ;
assert (ix >= 0 && ix < NINFLATIONLOCKS, "invariant") ;
assert ((NINFLATIONLOCKS & (NINFLATIONLOCKS-1)) == 0, "invariant") ;
//获取对应的膨胀锁
Thread::muxAcquire (InflationLocks + ix, "InflationLock") ;
while (obj->mark() == markOopDesc::INFLATING()) {
// 如果还是处于膨胀过程中
if ((YieldThenBlock++) >= 16) {
//让当前线程park
Thread::current()->_ParkEvent->park(1) ;
} else {
os::NakedYield() ;
}
}
//释放膨胀锁
Thread::muxRelease (InflationLocks + ix ) ;
TEVENT (Inflate: INFLATING - yield/park) ;
}
} else {
//执行自旋,实际就是直接返回0
SpinPause() ; // SMP-polite spinning
}
}
}
bool is_being_inflated() const { return (value() == 0); }
static markOop INFLATING() { return (markOop) 0; }
//指针数组,通过原子的修改数组元素的值来实现膨胀锁的功能
#define NINFLATIONLOCKS 256
static volatile intptr_t InflationLocks [NINFLATIONLOCKS] ;
bool is_neutral() const { return (mask_bits(value(), biased_lock_mask_in_place) == unlocked_value); }
bool has_monitor() const {
return ((value() & monitor_value) != 0);
}
bool Thread::is_lock_owned(address adr) const {
return on_local_stack(adr);
}
markOop displaced_mark_helper() const {
assert(has_displaced_mark_helper(), "check");
//去除对象头中的锁标识位
intptr_t ptr = (value() & ~monitor_value);
//注意此处是将ptr强转成markOop* 指针,然后获取该指针指向的值,即该对象原来的对象头
return *(markOop*)ptr;
}
该方法会根据对象是否持有锁以及锁的类型做不同的处理,如果是无锁的,则直接返回对象头中包含的hash码,如果对象头中不存在hash码则创建一个并在对象头中保存;如果持有轻量级锁,则根据对象头中保存的指向当前线程调用栈帧的指针找到该对象原有的对象头,如果对象头中包含有hash码则返回,如果没有则需要将当前对象的锁膨胀成监视器锁,并生成一个新的hash码保存到对象头中;如果持有监视器锁,即重量级锁,则根据对象头中保存的代表监视器锁的ObjectMonitor的指针获取关联的ObjectMonitor,从中获取保存的对象的原有对象头,如果包含hash码则返回,如果不包含则创建一个新的hash码并保存到对象头中。
2、get_next_hash
get_next_hash方法用于生成一个新的hash码,根据配置参数hashCode有不同的实现,从JDK6开始,该参数的默认值是5,此时采用Marsaglia's xor-shift随机算法给对象生成一个hash码,跟对象的内存地址没有任何关系,其实现如下:
static inline intptr_t get_next_hash(Thread * Self, oop obj) {
intptr_t value = 0 ;
//hashCode是一个配置选项,从JDK6开始,其默认值是5
if (hashCode == 0) {
//获取随机数
value = os::random() ;
} else
if (hashCode == 1) {
//根据对象地址计算
intptr_t addrBits = cast_from_oop<intptr_t>(obj) >> 3 ;
value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ;
} else
if (hashCode == 2) {
value = 1 ; // for sensitivity testing
} else
if (hashCode == 3) {
//返回一个序列值
value = ++GVars.hcSequence ;
} else
if (hashCode == 4) {
//直接返回对象地址
value = cast_from_oop<intptr_t>(obj) ;
} else {
// Marsaglia's xor-shift 算法,默认实现
//_hashStateX是线程创建时生成的随机数,
unsigned t = Self->_hashStateX ;
t ^= (t << 11) ;
//_hashStateY,_hashStateZ,_hashStateW初始化时是固定值
//通过重置_hashStateW,来动态改变_hashStateX,_hashStateY,_hashStateZ的属性
Self->_hashStateX = Self->_hashStateY ;
Self->_hashStateY = Self->_hashStateZ ;
Self->_hashStateZ = Self->_hashStateW ;
unsigned v = Self->_hashStateW ;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
Self->_hashStateW = v ;
value = v ;
}
//因为hash值是保存在对象头的特定位上,此处且运算,检查对应位的hash值是否是0
value &= markOopDesc::hash_mask;
if (value == 0) value = 0xBAD ;
assert (value != markOopDesc::no_hash, "invariant") ;
TEVENT (hashCode: GENERATE) ;
return value;
}
Thread的_hashStateY属性的调用链如下:
其中Thread::Thread()方法中的初始化逻辑如下:
上述方法是生成hash码的默认实现,在实际应用中可以按需来改写默认的hashCode方法的实现,以String的hashCode为例,在数据库的分库分表场景下通常需要根据某个字符串的hash值来计算某条记录需要存储进那种表中,这种场景下需要确保同一个字符串在不同的操作系统下,无论何时永远返回一个相同的hash码,参考如下测试用例:
public class StringTest {
public static void main(String[] args) {
System.out.println("Hello World".hashCode());
}
}
上述代码在Windows和Linux上无论运行多少次,永远返回-862545276,如果是默认的hashCode方法实现,肯定每次运行时其返回值都是不一样的,String是怎样做到同一个字符串的hashCode永远一样了?参考其hashCode方法的实现,如下:
public int hashCode() {
//hash是String类的一个属性,初始化为0
int h = hash;
if (h == 0 && value.length > 0) {
//如果hash未初始化且字符串不是空字符串
char val[] = value;
//根据字符串包含的字符来计算,所以字符串相同,计算出来的hash值始终相同
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
3、inflate / inflate_helper
inflate方法用于将某个对象持有的轻量级锁膨胀成重量级锁即监视器锁,inflate_helper是给JVM内部其他类使用的,也是基于inflate方法实现的,其调用链如下:
其实现如下:
ObjectMonitor* ObjectSynchronizer::inflate_helper(oop obj) {
markOop mark = obj->mark();
if (mark->has_monitor()) {
//如果该对象本身就是持有重量级锁则直接返回对象头中包含的ObjectMonitor指针
assert(ObjectSynchronizer::verify_objmon_isinpool(mark->monitor()), "monitor is invalid");
assert(mark->monitor()->header()->is_neutral(), "monitor must record a good object header");
return mark->monitor();
}
//如果没有持有监视器锁,则创建一个并保存在对象头中
return ObjectSynchronizer::inflate(Thread::current(), obj);
}
ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, oop object) {
assert (Universe::verify_in_progress() ||
!SafepointSynchronize::is_at_safepoint(), "invariant") ;
for (;;) {
const markOop mark = object->mark() ;
assert (!mark->has_bias_pattern(), "invariant") ;
// The mark can be in one of the following states:
// * Inflated - 已经持有监视器锁
// * Stack-locked - 持有轻量级锁,准备执行锁膨胀
// * INFLATING - 正在执行锁膨胀过程
// * Neutral - 未持有锁
// * BIASED - 持有偏向锁,不可能出现此情形,因为偏向锁只有膨胀成轻量级锁才会膨胀成重量级锁
// CASE: inflated
if (mark->has_monitor()) {
//如果已经持有监视器锁,则返回对象头中保存的ObjectMonitor指针
ObjectMonitor * inf = mark->monitor() ;
assert (inf->header()->is_neutral(), "invariant");
assert (inf->object() == object, "invariant") ;
assert (ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid");
return inf ;
}
// CASE: inflation in progress - inflating over a stack-lock.
if (mark == markOopDesc::INFLATING()) {
TEVENT (Inflate: spin while INFLATING) ;
//其他某个线程正在将该对象的锁膨胀成监视器锁,在此等待膨胀完成,会先自旋,超过1000次后yeild,yield 一定次数后执行park
ReadStableMark(object) ;
continue ;
}
// CASE: stack-locked
if (mark->has_locker()) {
//从当前线程的本地空闲链表或者全局空闲链表中分配一个空闲的ObjectMonitor
ObjectMonitor * m = omAlloc (Self) ;
// 将其重置
m->Recycle();
m->_Responsible = NULL ;
m->OwnerIsThread = 0 ;
m->_recursions = 0 ;
m->_SpinDuration = ObjectMonitor::Knob_SpinLimit ; // Consider: maintain by type/class
//将其对象头原子的修改为INFLATING
markOop cmp = (markOop) Atomic::cmpxchg_ptr (markOopDesc::INFLATING(), object->mark_addr(), mark) ;
if (cmp != mark) {
//如果修改失败则将m归还到本地线程的空闲链表,修改失败说明其他某个线程也在尝试执行锁膨胀
omRelease (Self, m, true) ;
continue ; //开始下一次循环
}
//根据对象头中的指针获取保存在当前线程栈帧中的对象原来的对象头
markOop dmw = mark->displaced_mark_helper() ;
assert (dmw->is_neutral(), "invariant") ;
//将原来的对象头保存
m->set_header(dmw) ;
m->set_owner(mark->locker());
m->set_object(object);
guarantee (object->mark() == markOopDesc::INFLATING(), "invariant") ;
//重置对象头
object->release_set_mark(markOopDesc::encode(m));
//增加计数
if (ObjectMonitor::_sync_Inflations != NULL) ObjectMonitor::_sync_Inflations->inc() ;
TEVENT(Inflate: overwrite stacklock) ;
if (TraceMonitorInflation) {
if (object->is_instance()) {
ResourceMark rm;
tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(void *) object, (intptr_t) object->mark(),
object->klass()->external_name());
}
}
return m ;
}
// CASE: neutral
assert (mark->is_neutral(), "invariant");
//分配一个新的ObjectMonitor
ObjectMonitor * m = omAlloc (Self) ;
//将其初始化
m->Recycle();
//保存原来的对象头,设置相关属性
m->set_header(mark);
m->set_owner(NULL);
m->set_object(object);
m->OwnerIsThread = 1 ;
m->_recursions = 0 ;
m->_Responsible = NULL ;
m->_SpinDuration = ObjectMonitor::Knob_SpinLimit ; // consider: keep metastats by type/class
if (Atomic::cmpxchg_ptr (markOopDesc::encode(m), object->mark_addr(), mark) != mark) {
//原子的修改对象头,如果修改失败将m恢复成初始状态
m->set_object (NULL) ;
m->set_owner (NULL) ;
m->OwnerIsThread = 0 ;
m->Recycle() ;
//归还到本地的空闲链表中
omRelease (Self, m, true) ;
m = NULL ;
continue ;//开始下一次循环
}
//对象头修改成功,增加计数
if (ObjectMonitor::_sync_Inflations != NULL) ObjectMonitor::_sync_Inflations->inc() ;
TEVENT(Inflate: overwrite neutral) ;
if (TraceMonitorInflation) {
if (object->is_instance()) {
ResourceMark rm;
tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(void *) object, (intptr_t) object->mark(),
object->klass()->external_name());
}
}
return m ;
}
}
BasicLock* locker() const {
assert(has_locker(), "check");
//获取对象头中保存的BasicLock
return (BasicLock*) value();
}
该方法会根据对象的锁状态来做不同的处理,如果已经持有监视器锁则直接返回对象头中包含的ObjectMonitor指针;如果处于锁膨胀的过程中,则通过自旋、yeild或者park的方式等待锁膨胀完成;如果对象持有轻量级锁或者无锁,则从线程本地的空闲ObjectMonitor链表或者全局的空闲ObjectMonitor链表中分配一个ObjectMonitor,将其重置并保存当前对象的对象头等属性,最后原子的修改对象的对象头,如果有其他线程也在尝试修改同一对象的对象头导致修改失败则将之前分配的ObjectMonitor归还到线程本地的空闲ObjectMonitor链表中,开始下一次循环,如果修改成功则返回ObjectMonitor实例。
4、omAlloc / omRelease / omFlush
omAlloc方法用于分配ObjectMonitor,具体分配时首先从当前线程保存的本地ObjectMonitor空闲列表中分配,如果本地ObjectMonitor空闲列表为空,则尝试从全局的ObjectMonitor空闲列表中分配最多32个ObjectMonitor实例将其存入线程本地的ObjectMonitor空闲链表中,然后从中分配ObjectMonitor;如果本地ObjectMonitor空闲列表和全局的ObjectMonitor空闲列表都为空,则一次创建128个ObjectMonitor实例,将其加入到全局的ObjectMonitor空闲列表中。使用本地的ObjectMonitor空闲列表可以减少从全局的ObjectMonitor空闲列表中分配时的锁竞争问题和一致性问题,提高分配效率,但是会增加GC时根节点扫描的开销。其调用链如下:
omRelease用于将某个ObjectMonitor归还到本地的ObjectMonitor空闲链表中,如果MonitorInUseLists为true还需要将其从全局的正在使用的ObjectMonitor链表中移除。其调用链如下:
omFlush是在线程退出时调用,将该线程的本地ObjectMonitor空闲链表中的元素归还到全局空闲链表中,将本地正在使用的ObjectMonitor链表中的元素归还到全局正在使用的链表,为啥这是不能将本地正在使用的ObjectMonitor链表中的元素归还到全局空闲链表中了?因为其中的某个ObjectMonitor实例也可能被其他线程所使用,其调用链如下:
上述方法的实现如下:
ObjectMonitor * ATTR ObjectSynchronizer::omAlloc (Thread * Self) {
const int MAXPRIVATE = 1024 ;
for (;;) {
ObjectMonitor * m ;
// 1: try to allocate from the thread's local omFreeList.
m = Self->omFreeList ;
if (m != NULL) {
//如果线程本地的空闲链表非空,从空闲链表中分配一个
Self->omFreeList = m->FreeNext ;
Self->omFreeCount -- ;
guarantee (m->object() == NULL, "invariant") ;
//MonitorInUseLists表示是否记录使用中的ObjectMonitor,默认为false
if (MonitorInUseLists) {
//如果为true则将其加入到omInUseList中
m->FreeNext = Self->omInUseList;
Self->omInUseList = m;
Self->omInUseCount ++;
// verifyInUse(Self);
} else {
//如果为false,将FreeNext置为NULL
m->FreeNext = NULL;
}
return m ;
}
// 2: try to allocate from the global gFreeList
//线程本地的空闲链表为空,尝试从全局的空闲链表中分配
if (gFreeList != NULL) {
//获取锁ListLock
Thread::muxAcquire (&ListLock, "omAlloc") ;
for (int i = Self->omFreeProvision; --i >= 0 && gFreeList != NULL; ) {
//从全局链表中取出一个
MonitorFreeCount --;
ObjectMonitor * take = gFreeList ;
gFreeList = take->FreeNext ;
guarantee (take->object() == NULL, "invariant") ;
guarantee (!take->is_busy(), "invariant") ;
//将取出的ObjectMonitor重置
take->Recycle() ;
//将ObjectMonitor加入到线程本地的空闲链表中
omRelease (Self, take, false) ;
}
//释放锁
Thread::muxRelease (&ListLock) ;
//将omFreeProvision增加一半,如果超过MAXPRIVATE则置为MAXPRIVATE
Self->omFreeProvision += 1 + (Self->omFreeProvision/2) ;
if (Self->omFreeProvision > MAXPRIVATE ) Self->omFreeProvision = MAXPRIVATE ;
TEVENT (omFirst - reprovision) ;
//MonitorBound默认为0,表示允许使用的ObjectMonitor的最大个数
const int mx = MonitorBound ;
if (mx > 0 && (MonitorPopulation-MonitorFreeCount) > mx) {
//通过VM_Operation强制JVM进入安全点并调用deflate_idle_monitors方法回收部分空闲的ObjectMonitor
InduceScavenge (Self, "omAlloc") ;
}
//从全局的空闲链表中分配指定数量的空闲ObjectMonitor后就开始下一次循环,在本地空闲链表中分配
continue;
}
// 3: allocate a block of new ObjectMonitors
//本地空闲链表和全局的空闲链表都是空的,需要重新分配
//_BLOCKSIZE是一个枚举值,默认128
assert (_BLOCKSIZE > 1, "invariant") ;
//创建一个ObjectMonitor数组,即一次创建128个ObjectMonitor
ObjectMonitor * temp = new ObjectMonitor[_BLOCKSIZE];
if (temp == NULL) {
//分配失败,抛出异常
vm_exit_out_of_memory (sizeof (ObjectMonitor[_BLOCKSIZE]), OOM_MALLOC_ERROR,
"Allocate ObjectMonitors");
}
//将数组中的ObjectMonitor构成链表
for (int i = 1; i < _BLOCKSIZE ; i++) {
temp[i].FreeNext = &temp[i+1];
}
//数组中最后一个ObjectMonitor的FreeNext置为NULL
temp[_BLOCKSIZE - 1].FreeNext = NULL ;
//第一个元素标记为正在构建链表中
temp[0].set_object(CHAINMARKER);
//获取锁
Thread::muxAcquire (&ListLock, "omAlloc [2]") ;
//增加计数
MonitorPopulation += _BLOCKSIZE-1;
MonitorFreeCount += _BLOCKSIZE-1;
//将第一个数组元素加入到gBlockList中,gBlockList用于遍历所有的ObjectMonitor实例,无论其是空闲还是正在使用
temp[0].FreeNext = gBlockList;
gBlockList = temp;
//将第二个元素加入gFreeList中
temp[_BLOCKSIZE - 1].FreeNext = gFreeList ;
gFreeList = temp + 1;
//释放锁
Thread::muxRelease (&ListLock) ;
TEVENT (Allocate block of monitors) ;
}
}
void ObjectSynchronizer::omRelease (Thread * Self, ObjectMonitor * m, bool fromPerThreadAlloc) {
guarantee (m->object() == NULL, "invariant") ;
// Remove from omInUseList
//MonitorInUseLists默认为false
if (MonitorInUseLists && fromPerThreadAlloc) {
ObjectMonitor* curmidinuse = NULL;
//遍历omInUseList,如果存在目标m则将其移除
for (ObjectMonitor* mid = Self->omInUseList; mid != NULL; ) {
if (m == mid) {
if (mid == Self->omInUseList) {
//如果位于链表头
Self->omInUseList = mid->FreeNext;
} else if (curmidinuse != NULL) {
//如果位于链表中间
curmidinuse->FreeNext = mid->FreeNext; // maintain the current thread inuselist
}
Self->omInUseCount --;
// verifyInUse(Self);
break;
} else {
//curmidinuse表示当前mid的上一个ObjectMonitor
curmidinuse = mid;
mid = mid->FreeNext;
}
}
}
//将m加入到当前线程的空闲链表中
m->FreeNext = Self->omFreeList ;
Self->omFreeList = m ;
Self->omFreeCount ++ ;
}
void ObjectSynchronizer::omFlush (Thread * Self) {
ObjectMonitor * List = Self->omFreeList ; // Null-terminated SLL
Self->omFreeList = NULL ;
ObjectMonitor * Tail = NULL ;
int Tally = 0;
if (List != NULL) {
ObjectMonitor * s ;
//遍历本地空闲链表中的ObjectMonitor,找到最后一个元素
for (s = List ; s != NULL ; s = s->FreeNext) {
Tally ++ ;
Tail = s ;
guarantee (s->object() == NULL, "invariant") ;
guarantee (!s->is_busy(), "invariant") ;
s->set_owner (NULL) ; // redundant but good hygiene
TEVENT (omFlush - Move one) ;
}
guarantee (Tail != NULL && List != NULL, "invariant") ;
}
ObjectMonitor * InUseList = Self->omInUseList;
ObjectMonitor * InUseTail = NULL ;
int InUseTally = 0;
if (InUseList != NULL) {
Self->omInUseList = NULL;
ObjectMonitor *curom;
//遍历本地正在使用中的ObjectMonitor链表,找到最后一个
for (curom = InUseList; curom != NULL; curom = curom->FreeNext) {
InUseTail = curom;
InUseTally++;
}
// TODO debug
assert(Self->omInUseCount == InUseTally, "inuse count off");
Self->omInUseCount = 0;
guarantee (InUseTail != NULL && InUseList != NULL, "invariant");
}
//获取锁
Thread::muxAcquire (&ListLock, "omFlush") ;
if (Tail != NULL) {
//将本地空闲ObjectMonitor链表归还到全局空闲链表中
Tail->FreeNext = gFreeList ;
gFreeList = List ;
MonitorFreeCount += Tally;
}
if (InUseTail != NULL) {
//将本地正在使用中的ObjectMonitor链表归还到全局正在使用链表
InUseTail->FreeNext = gOmInUseList;
gOmInUseList = InUseList;
gOmInUseCount += InUseTally;
}
//释放锁
Thread::muxRelease (&ListLock) ;
TEVENT (omFlush) ;
}
Thread中定义的ObjectMonitor链表的相关属性如下:
omFreeList就是ObjectMonitor空闲链表,omFreeCount就是空间链表包含的个数,omFreeProvision是从全局的空闲链表中获取若干个ObjectMonitor到本地空闲链表时能够获取的最大数量,omInUseList是正在使用中的ObjectMonitor列表,omInUseCount表示正在使用中的ObjectMonitor的个数,上述属性在Thread的构造方法中的初始化如下:
5、InduceScavenge / deflate_idle_monitors / deflate_monitor / walk_monitor_list
当设置了MonitorBound属性时,如果当前已使用的ObjectMonitor超过该属性时就会通过InduceScavenge强制JVM进入安全点,进入安全点后会执行deflate_idle_monitors方法来清理掉已经从本地或者全局空闲链表中分配出去了但是不被使用的ObjectMonitor实例,将其归还到全局的空闲链表中。该属性默认为0,即默认情况下只有在执行GC等需要在安全点下执行的操作时才会触发ObjectMonitor的回收,除此之外ObjectMonitor的数量会一直增长。
InduceScavenge的调用链如下:
其实现如下:
static void InduceScavenge (Thread * Self, const char * Whence) {
//ForceMonitorScavenge是一个static volatile变量,初始为0,用来控制InduceScavenge不会重复执行
if (ForceMonitorScavenge == 0 && Atomic::xchg (1, &ForceMonitorScavenge) == 0) {
if (ObjectMonitor::Knob_Verbose) {
::printf ("Monitor scavenge - Induced STW @%s (%d)\n", Whence, ForceMonitorScavenge) ;
::fflush(stdout) ;
}
//执行VM_ForceAsyncSafepoint
VMThread::execute (new VM_ForceAsyncSafepoint()) ;
if (ObjectMonitor::Knob_Verbose) {
::printf ("Monitor scavenge - STW posted @%s (%d)\n", Whence, ForceMonitorScavenge) ;
::fflush(stdout) ;
}
}
}
VM_ForceAsyncSafepoint的定义如下:
其doit方法是一个空实现,evaluation_mode方法表明其需要在安全点下执行。在SafepointSynchronize::begin方法完成了安全点同步,即所有线程都停下来后,会执行do_cleanup_tasks方法,该方法会调用deflate_idle_monitors清理空闲的ObjectMonitor,如下图:
deflate_idle_monitors的调用链如下:
如果MonitorInUseLists为true,deflate_idle_monitors依赖walk_monitor_list遍历所有线程的本地omInUseList链表和全局的gOmInUseList,如果链表中的ObjectMonitor未被使用则将其归还到一个链表中;如果MonitorInUseLists为false,deflate_idle_monitors则依赖deflate_monitor,通过gBlockList遍历所有的已创建的ObjectMonitor实例,如果其Object为非空即已经被分配出去了但是未被使用则将其回收,归还到某个链表中;walk_monitor_list处理链表中的ObjectMonitor实例时,也是调用deflate_monitor方法;最后将所有归还的ObjectMonitor实例构成的链表插入到全局空闲链表gFreeList的前面。参考deflate_monitor方法的调用链,如下:
这三个方法的实现如下:
void ObjectSynchronizer::deflate_idle_monitors() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
int nInuse = 0 ; // currently associated with objects
int nInCirculation = 0 ; // extant
int nScavenged = 0 ; // reclaimed
bool deflated = false;
ObjectMonitor * FreeHead = NULL ; // Local SLL of scavenged monitors
ObjectMonitor * FreeTail = NULL ;
TEVENT (deflate_idle_monitors) ;
//获取锁
Thread::muxAcquire (&ListLock, "scavenge - return") ;
//MonitorInUseLists默认为false
if (MonitorInUseLists) {
int inUse = 0;
for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
nInCirculation+= cur->omInUseCount;
//遍历线程本地的omInUseList链表中的ObjectMonitor,如果其未使用则将其回收,返回该链表中被回收掉的ObjectMonitor个数
int deflatedcount = walk_monitor_list(cur->omInUseList_addr(), &FreeHead, &FreeTail);
cur->omInUseCount-= deflatedcount;
//nScavenged表示累计回收掉的ObjectMonitor数量
nScavenged += deflatedcount;
//nInuse表示累计的正在使用中的ObjectMonitor数量
nInuse += cur->omInUseCount;
}
// For moribund threads, scan gOmInUseList
if (gOmInUseList) {
nInCirculation += gOmInUseCount;
//遍历全局的gOmInUseList链表中的ObjectMonitor
int deflatedcount = walk_monitor_list((ObjectMonitor **)&gOmInUseList, &FreeHead, &FreeTail);
gOmInUseCount-= deflatedcount;
nScavenged += deflatedcount;
nInuse += gOmInUseCount;
}
} else for (ObjectMonitor* block = gBlockList; block != NULL; block = next(block)) {
//通过gBlockList链表遍历所有已创建的ObjectMonitor,其中每个元素都是一个ObjectMonitor数组的头元素
assert(block->object() == CHAINMARKER, "must be a block header");
nInCirculation += _BLOCKSIZE ;
for (int i = 1 ; i < _BLOCKSIZE; i++) {
ObjectMonitor* mid = &block[i];
oop obj = (oop) mid->object();
if (obj == NULL) {
//obj为空说明其未被分配出去,还在本地或者全局空闲链表中
guarantee (!mid->is_busy(), "invariant") ;
continue ;
}
//如果该ObjectMonitor未使用则将其插入到FreeTail链表中
deflated = deflate_monitor(mid, obj, &FreeHead, &FreeTail);
if (deflated) {
//未被使用,将其FreeNext置为null,因为在分配该ObjectMonitor时已经将该ObjectMonitor从空闲链表中移除了,所以此处不需要再次将其从空闲链表中移除
mid->FreeNext = NULL ;
nScavenged ++ ;
} else {
nInuse ++;
}
}
}
//增加空闲计数
MonitorFreeCount += nScavenged;
// Consider: audit gFreeList to ensure that MonitorFreeCount and list agree.
if (ObjectMonitor::Knob_Verbose) {
::printf ("Deflate: InCirc=%d InUse=%d Scavenged=%d ForceMonitorScavenge=%d : pop=%d free=%d\n",
nInCirculation, nInuse, nScavenged, ForceMonitorScavenge,
MonitorPopulation, MonitorFreeCount) ;
::fflush(stdout) ;
}
ForceMonitorScavenge = 0; // Reset
//如果回收掉了ObjectMonitor实例
if (FreeHead != NULL) {
guarantee (FreeTail != NULL && nScavenged > 0, "invariant") ;
assert (FreeTail->FreeNext == NULL, "invariant") ;
//将FreeTail插入到gFreeList的后面
FreeTail->FreeNext = gFreeList ;
gFreeList = FreeHead ;
}
//释放锁
Thread::muxRelease (&ListLock) ;
// 增加计数
if (ObjectMonitor::_sync_Deflations != NULL) ObjectMonitor::_sync_Deflations->inc(nScavenged) ;
if (ObjectMonitor::_sync_MonExtant != NULL) ObjectMonitor::_sync_MonExtant ->set_value(nInCirculation);
// 增加计数
GVars.stwRandom = os::random() ;
GVars.stwCycle ++ ;
}
int ObjectSynchronizer::walk_monitor_list(ObjectMonitor** listheadp,
ObjectMonitor** FreeHeadp, ObjectMonitor** FreeTailp) {
ObjectMonitor* mid;
ObjectMonitor* next;
ObjectMonitor* curmidinuse = NULL;
int deflatedcount = 0;
for (mid = *listheadp; mid != NULL; ) {
oop obj = (oop) mid->object();
bool deflated = false;
if (obj != NULL) {
deflated = deflate_monitor(mid, obj, FreeHeadp, FreeTailp);
}
if (deflated) {
//如果未使用被回收了,则将其从listheadp中移除
if (mid == *listheadp) {
*listheadp = mid->FreeNext;
} else if (curmidinuse != NULL) {
curmidinuse->FreeNext = mid->FreeNext; // maintain the current thread inuselist
}
next = mid->FreeNext;
mid->FreeNext = NULL; // This mid is current tail in the FreeHead list
mid = next;
//增加计数
deflatedcount++;
} else {
curmidinuse = mid;
mid = mid->FreeNext;
}
}
return deflatedcount;
}
bool ObjectSynchronizer::deflate_monitor(ObjectMonitor* mid, oop obj,
ObjectMonitor** FreeHeadp, ObjectMonitor** FreeTailp) {
bool deflated;
// Normal case ... The monitor is associated with obj.
guarantee (obj->mark() == markOopDesc::encode(mid), "invariant") ;
guarantee (mid == obj->mark()->monitor(), "invariant");
guarantee (mid->header()->is_neutral(), "invariant");
if (mid->is_busy()) {
//如果ObjectMonitor正在使用中,返回false
if (ClearResponsibleAtSTW) mid->_Responsible = NULL ;
deflated = false;
} else {
//如果ObjectMonitor未使用则回收,将其归还FreeTailp空闲链表中,返回true
TEVENT (deflate_idle_monitors - scavenge1) ;
if (TraceMonitorInflation) {
if (obj->is_instance()) {
ResourceMark rm;
tty->print_cr("Deflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(void *) obj, (intptr_t) obj->mark(), obj->klass()->external_name());
}
}
//恢复原来的对象头
obj->release_set_mark(mid->header());
//重置
mid->clear();
assert (mid->object() == NULL, "invariant") ;
//将其插入到空闲链表中
if (*FreeHeadp == NULL) *FreeHeadp = mid;
if (*FreeTailp != NULL) {
ObjectMonitor * prevtail = *FreeTailp;
assert(prevtail->FreeNext == NULL, "cleaned up deflated?"); // TODO KK
prevtail->FreeNext = mid;
}
*FreeTailp = mid;
deflated = true;
}
return deflated;
}
6、wait / notify / notifyall
这三个方法就是Object的wait,notify,notifyAll方法的核心实现,wait方法会分配一个与该对象关联的ObjectMonitor然后调用其wait方法;notify和notifyall会校验对象是否持有轻量级锁,如果有则直接返回,因为如果持有轻量级锁说明其未调用wait方法,没有与之关联的ObjectMonitor实例,如果没有则获取关联的ObjectMonitor实例,调用其notify和notifyall方法,在执行具体的逻辑前会检查获取的ObjectMonitor实例是否是当前线程持有的,如果不是会抛出异常ObjectMonitor实例,如果先调用wait方法再调用notify或者notifyall方法则不报错。其实现如下:
void ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) {
//UseBiasedLocking默认为true
if (UseBiasedLocking) {
//撤销对象头中包含的偏向锁
BiasedLocking::revoke_and_rebias(obj, false, THREAD);
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
if (millis < 0) {
TEVENT (wait - throw IAX) ;
//参数非法抛出异常
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
}
//分配一个关联的ObjectMonitor实例
ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj());
DTRACE_MONITOR_WAIT_PROBE(monitor, obj(), THREAD, millis);
//调用其wait方法
monitor->wait(millis, true, THREAD);
dtrace_waited_probe(monitor, obj, THREAD);
}
void ObjectSynchronizer::notify(Handle obj, TRAPS) {
if (UseBiasedLocking) {
//撤销对象头中包含的偏向锁
BiasedLocking::revoke_and_rebias(obj, false, THREAD);
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
markOop mark = obj->mark();
if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) {
//如果该对象持有轻量级锁则直接返回,持有轻量级锁说明其对象头中没有包含ObjectMonitor指针
return;
}
//获取与之关联的ObjectMonitor实例,调用其notify方法
ObjectSynchronizer::inflate(THREAD, obj())->notify(THREAD);
}
// NOTE: see comment of notify()
void ObjectSynchronizer::notifyall(Handle obj, TRAPS) {
if (UseBiasedLocking) {
//撤销对象头中包含的偏向锁
BiasedLocking::revoke_and_rebias(obj, false, THREAD);
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
markOop mark = obj->mark();
if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) {
//如果该对象持有轻量级锁则直接返回
return;
}
//获取与之关联的ObjectMonitor实例,调用其notify方法
ObjectSynchronizer::inflate(THREAD, obj())->notifyAll(THREAD);
}