1,对象的内存布局
- 当我们 new 出一个对象出来,这个对象在内存中到底是怎么分布的,这就叫对象的内存布局!这取决特定的JVM实现机,对于 hotsopt来讲。
-
MarkWord :给对象上锁(Synchronized),就是修改对象markword的值,因此MarkWord中记入了对象上锁的信息。(JC,hashcode的信息)
-
类指针classpointer:通过它的值能找到类所在的位置。
-
成员变量:
-
‘8字节对齐’:若1、2、3 的总字节数相加不是8的倍数,则在最后会有一些字节补充使成为8的整数倍。
2,Synchronized锁的升级过程
- 锁的升级过程为:
-
无锁(001):
-
偏向锁(101):通常情况下只有一个线程访问,只需将线程ID(指针指向)写 入MarkWord中,及锁偏向改线程的意思。无竞争、效率较高!
-
轻量级锁(自旋锁)(00):当多个线程来竞争 无锁 或 偏向锁 时,撤销偏向锁,多个线程间进行竞争。怎么竞争?:每个线程在自己的线程栈生成LockRecord(LR),当对象的 类指针classpointer 指向A线程的LR时,A线程就抢占了这把轻量级锁;B线程继续竞争,通过CAS的方式自旋的等待线程A释放改锁,再使用改锁。
-
重量级锁(10):当线程竞争加剧,即当有线程自旋超过10,或者竞争的线程数超过CPU核心数的一半时。 jdk1.6之后又JVM自己实现。
-
GC标记(11):11
-
3,锁升级初步
- 偏向锁与轻量级锁(自旋锁)都是用户空间锁,在用户空间完成不需要与操作系统交互。
- 重量级锁是需要向操作系统内核申请资源的。
提问?
1. 为什么有自旋锁还需要重量级锁?
- 自旋的过程是需要CPU资源的,如果锁的时间过长、或自旋的线程过多就会大量消耗CPU资源;而重量级锁有等待队列,当拿不到锁就会进入等待队列(阻塞),从而不需要消耗CPU资源。
2.偏向锁是否一定比自旋锁效率高
- 不一定!因为偏向锁需要撤销锁的过程,因此在明知道有多个线程竞争锁的情况下,默认时不打开偏向锁的,例如JVM启动时就有多个线程竞争,就不会打开偏向锁,过段时间在打开。简单来说就是,在多线程环境下,偏向锁的撤销锁的过程显得多此一举。