4.9.1 面试题
12、你觉得目前面试,你还有那些方面理解的比较好,我没问到的,我说了juc和 jvm以及 同步锁机制
那先说juc吧,说下aqs的大致流程3、
14、cas自旋锁,是获取不到锁就一直自旋吗? cas和synchronized区别在哪里,为什么cas好,具体优势在哪里,我说cas避免cpu切换线程的开销,又问我在自旋的这个线程能保证一直占用cpu吗?假如cpu放弃了这个线程,不是还要带来线程再次抢占cpu的开销?
15、synchronized底层如何实现的,实现同步的时候用到cas了吗?具体哪里用到了
16、我说上个问题的时候说到了对象头,问我对象头存储哪些信息,长度是多少位存储
4.9.2 对象在堆内存中布局
在HotSpot虚拟机中,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header),实例数据(Instance Data),和对齐填充(Padding)
- 对象实例
- 对象头
- 对象标记(Mark Word):HashCode,GC标记,GC存活次数,同步锁标记,偏向锁持有者
- 类元信息(又叫类型指针):指向该对象类元数据(klass)的首地址
- 长度(数组对象特有)
- 实例数据(属性数据)
- 对齐填充(保证8字节的倍数)
- 对象头
在64位系统中,Mark Word占用8字节,类元信息占用8字节,一共是16字节。
Object obj = new Object(); // obj占用16字节的数据
// 类元信息(类型指针) Customer c1 = new Customer(); // c1中的类型指针指向了Customer类class Customer{ int id; // 实例数据 }
JOL查看Java对象内存布局
<!-- JOL依赖 JOL查看Java对象内存布局-->
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.9</version>
</dependency>
- 两种方式
- 开启偏向锁无等待
-XX:BiasedLockingStartupDelay=0
- 使用Sleep
- 开启偏向锁无等待
public class JOLTest {public static void main(String[] args) throws InterruptedException {Object o = new Object();TimeUnit.SECONDS.sleep(5);synchronized (o) {System.out.println(ClassLayout.parseInstance(o).toPrintable());}}
}
(1) 对象标记MarkWord
分代年龄最大为15,因为对象标记(MarkWord)中GC存活次数只占4个bit位,只能表示 0 ~ 15