阅读本文前,你需要对轻量级锁有所了解。轻量级锁在ObjectSynchronizer::slow_enter里尝试获取,所以要先加个断点。
当他进来的时候,可以看到:
1
2 3 |
Breakpoint 2, ObjectSynchronizer::slow_enter (obj=..., lock=0x7ffff7fe16e8, __the_thread__=0x7ffff000bb38)
at /home/geym/openjdk/openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp:228 228 markOop mark = obj->mark(); |
第一句就是获取对象头。然后打印一下lock看看。
1
2 3 4 |
(gdb) print lock
$62 = (BasicLock *) 0x7ffff7fe16e8 (gdb) print *lock $63 = {_displaced_header = 0x7ffff000c5b8} |
下一步走起
1
2 3 4 |
(gdb) n
229 assert(!mark->has_bias_pattern(), "should not see bias pattern here"); (gdb) n 231 if (mark->is_neutral()) { |
看看mark
1
2 3 4 |
(gdb) print mark
$64 = (markOop) 0x1 (gdb) print &mark $65 = (markOop *) 0x7ffff7fe15d8 |
继续
1
2 |
(gdb) n
234 lock->set_displaced_header(mark); |
上面就是把对象头mark先保存在锁里(因为马上要改变mark了,要备份一下),继续走起。
1
2 3 4 5 6 7 8 9 10 |
(gdb) n
235 if (mark == (markOop) Atomic::cmpxchg_ptr(lock, obj()->mark_addr(), mark)) { (gdb) print obj.obj() $66 = (oopDesc *) 0x40d204750 (gdb) print *obj.obj() $67 = {_mark = 0x1, _metadata = {_klass = 0x81a40048, _compressed_klass = 2175008840}, static _bs = 0x7ffff001f4c8} (gdb) print obj.obj()->mark_addr() $68 = (markOop *) 0x40d204750 (gdb) print *obj.obj()->mark_addr() $69 = (markOop) 0x1 |
看到对象头mark了吧。修改之前是0×1。然后就是cas赋值了。继续走起
1
2 3 4 5 6 7 8 |
(gdb) n
237 return ; (gdb) print obj.obj() $70 = (oopDesc *) 0x40d204750 (gdb) print *obj.obj() $71 = {_mark = 0x7ffff7fe16e8, _metadata = {_klass = 0x81a40048, _compressed_klass = 2175008840}, static _bs = 0x7ffff001f4c8} (gdb) print *lock $72 = {_displaced_header = 0x1} |
修改之后,对象头mark变成了锁的地址,锁的地址在最开始就打印过,看看就是一样的。这个锁的位置是在线程栈里。判断线程是不是持有轻量级锁,看看对象头的地址有没有在线程栈的范围里就可以了。而线程栈中的这个锁,还备份着原来对象头的mark。
轻量级锁就是这样的。