当前位置:网站首页>对象头和synchronized的升级
对象头和synchronized的升级
2022-08-02 14:16:00 【微生鸿朗】
一、线程的历史
二、CAS的原理模型
CAS全拼又叫做compareAndSwap,从名字上的意思就知道是比较交换的意思、它是一条CPU并发原语。它包含 3 个参数 CAS(V,E,N),V表示要更新变量的值,E表示预期值,N表示新值。仅当 V值等于E值时,才会将V的值设为N,如果V值和E值不同,则说明已经有其他线程做两个更新,则当前线程则什么都不做。最后,CAS 返回当前V的真实值。
三、对象头的理解
1、对象在内存中的存储情况
注释:Markword 对象头占用8字节 、class pointer 类型指针占用4个字节 、instance data 实例数据、padding 对齐(主要作用是补齐字节数,达到被8整除的状态)。
- 小知识
C:\>java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=131697344 -XX:MaxHeapSize=2107157504 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.8.0_291"
Java(TM) SE Runtime Environment (build 1.8.0_291-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.291-b10, mixed mode)
解释:在这个指令中,可以打印出的参数的类型
-XX:InitialHeapSize=131697344表示的是起始的堆大小,
-XX:MaxHeapSize=2107157504表示的是最大的堆的大小
-XX:+PrintCommandLineFlags表示的是输入的堆的大小
-XX:+UseCompressedClassPointers表示的是压缩指针,占用4个字节
-XX:+UseCompressedOops表示的是普通对象指针,默认是压缩的4个字节
-XX:+UseCompressedOops
Java的指针的长度是64位,8个字节的,在默认开启了指针压缩后,会压缩成为4个字节
2、实际操作
2.1引入maven依赖
<!-- 引入jol工具的依赖-->
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.11</version>
</dependency>
</dependencies>
2.2写入测试代码
public class T01 {
public static void main(String[] args) {
Object o = new Object();
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
}
解释:
2.3执行方法后的结果
Connected to the target VM, address: '127.0.0.1:61099', transport: 'socket'
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) e5 01 00 20 (11100101 00000001 00000000 00100000) (536871397)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
在图片中可以看到对象头是占用了8个字节,压缩指针占用4个字节,在后面由于不能被8整除,使用字节进行补齐。
四、锁状态的描述
解释:图中的unused表示没有使用,位数对应的值在该状态下使用的位数。
1、无锁状态:25位没有用;31位装的identity Hashcode,但是只有在被调用的时候,才填充,没有调用的时候是空的;1位没有使用的;4位分代年龄;1位偏向锁位;2位锁标志位。
2、偏向锁:54位存下当前线程的ID;2位存批量撤销Epoch;1位没有使用;4位分代年龄;1位偏向锁位;2位锁标志位。
3、自旋锁:62位指向线程中的Lock Record的指针。Lock Record与锁重入有关,synchronize默认是可重入的。自旋锁在竞争锁的时候,会在自己的内存的线程栈中创建一个Lock Record对象,抢到锁对象的资源时,锁对象头存的就是这个线程的Lock Record对象的指针,所以在重入的时候,会再创建一个Lock Record对象,利用Lock Record来记录到底琐了多少次。解锁的时候,就将一个Lock Record移除,移除的方式是FILO,也就是先进后出的原则。
4、重量级琐:重量级琐是在C++代码层面进行的,会生成一个ObjectMonitor对象,这个对象中记录了一系列的队列,
5、 分代年龄:JVM有10种垃圾回收器,前面7种都涉及分代年龄,采用分代算法。当我们创建一个对象的时候,把它放在年轻代中,每经过一次垃圾回收后年龄就+1,也就是垃圾回收无法回收掉这个对象,它的年龄就会不断的增长,到达15,因为4个字节最大为15,就转到老龄代,年轻代的回收就不再对它进行回收。
五、synchronized的升级过程
注意:
(1) 琐升级路线:new -> 偏向锁 -> 轻量级琐(自旋锁、自适应自旋锁) -> 重量级琐
(2) 如果偏向锁没有启动,那么new出来的对象是普通对象;如果偏向锁已经启动,那么new出来的对象就是匿名偏向对象。
(3) 偏向锁什么情况下转为轻量级琐呢?只要有2个线程竞争同一个琐资源,所有线程都升级为轻量级琐,也就是都会自旋抢占琐资源。
(4) 自旋锁在竞争资源的时候,也是CAS操作,用CAS的方式修改琐对象的mackword。
(5) 自旋锁升级为重量级琐需要符合什么条件呢?jdk1.6以前,某个线程自旋次数上限达到默认的10次,会升级为重量级锁,因为一直自旋消耗CPU资源;自旋线程数量达到了默认是系统的CPU核数的1/2的时候,全部升级为重量级琐进入等待队列。jdk1.6之后,jdk提供了自适应自旋,jdk根据每个线程的运行情况来判断是否需要升级。
六、总结
主要通过学习,了解对象头的相关知识和synchronized的升级过程。如有不对的地方敬请指导交流。
边栏推荐
猜你喜欢
大厂年薪50w+招聘具有测试平台开发能力的测试工程师
The relationship between base classes and derived classes [inheritance] / polymorphism and virtual functions / [inheritance and polymorphism] abstract classes and simple factories
Vmware workstation16 安装 ESXi 6.7 详细步骤
基类和派生类的关系【继承】/多态和虚函数/【继承和多态】抽象类和简单工厂
【软件测试】概念篇
Technical Selection of Message Queuing
抽象队列同步器AQS应用Lock详解
synchronized详解
【线程网络】了解线程属性(fork/interview question)
5款最好用的免费3D建模软件(附下载链接)
随机推荐
Xshell 使用删除键乱码问题
The use of a semaphore/interprocess communication 】 【 Shared memory
【软件测试】测试基础讲解
你的站点可能还没有准备好用于Site KitSite Kit 无法访问 WordPress REST API。请确保其已在您的站点上启用。
JMM&synchronized&volatile详解
implement tcp copa on ns3
win10无法识别蓝牙麦克风
【线程安全】用户级,内核级,组合级线程|线程同步的处理(条件变量)|strtok_r(可冲入函数)
【进程间通信】:管道通信/有名/无名
Mysql索引优化二
change the available bandwidth of tcp flow dynamically in mininet
代码细节带来的极致体验,ShardingSphere 5.1.0 性能提升密钥
Vmware workstation16 安装 ESXi 6.7 详细步骤
ssm整合
Mysql开启日志并按天进行分割
【进程间通信】信号量的使用/共享内存
OpenPose run command ([email protected])
深入理解负载均衡
【线程】线程创建 | 理解线程并发 (1)
CPU缓存一致性协议MESI