synchronized的底层原理

Synchronized的底层实现原理(看这篇就够了) 谈到多线程就不得不谈到Synchronized,重要性不言而喻,今天主要分享Synchronized的底层实现。 标题Synchronized synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized 翻译为中文的意思是同步,也称之为”同步锁“。 synchronized的作用是保证在同一时刻, 被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的效果。 标题Synchronized的使用方式 主要有3种使用方式: 1.修饰实例方法:作用于当前实例加锁 pu. 阅读详情

synchronized使用方式

我们知道并发编程会产生各种问题的源头是可见性,原子性,有序性。
而synchronized能同时保证可见性,原子性,有序性。所以我们在解决并发问题的时候经常用synchronized,当然还有很多其他工具,如volatile。但是volatile只能保证可见性,有序性,不能保证原子性。参见之前的文章volatile关键字——保证并发编程中的可见性、有序性

synchronized可以用在如下地方

  1. 修饰实例方法,对当前实例对象this加锁
  2. 修饰静态方法,对当前类的Class对象加锁
  3. 修饰代码块,指定加锁对象,对给定对象加锁

修饰实例方法

public class SynchronizedDemo {
    
    public synchronized void methodOne() {
    
    }
}

修饰静态方法

public class SynchronizedDemo {

    public static synchronized void methodTwo() {

    }
}

修饰代码块

public class SynchronizedDemo {

    public void methodThree() {
    	// 对当前实例对象this加锁
        synchronized (this) {
        
        }
    }

    public void methodFour() {
    	// 对class对象加锁
        synchronized (SynchronizedDemo.class) {
        
        }
    }
}

synchronized实现原理

Java对象组成

我们都知道对象是放在堆内存中的,对象大致可以分为三个部分,分别是对象头,实例变量和填充字节在这里插入图片描述

  1. 对象头,主要包括两部分1. Mark Word (标记字段),2.Klass Pointer(类型指针)。Klass Point 是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。Mark Word用于存储对象自身的运行时数据
  2. 实例变量,存放类的属性数据信息,包括父类的属性信息,这部分内存按4字节对齐
  3. 填充数据,由于虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐

synchronized不论是修饰方法还是代码块,都是通过持有修饰对象的锁来实现同步,那么synchronized锁对象是存在哪里的呢?答案是存在锁对象的对象头Mark Word,来看一下Mark Word存储了哪些内容?

由于对象头的信息是与对象自身定义的数据没有关系的额外存储成本,因此考虑到JVM的空间效率,Mark Word 被设计成为一个非固定的数据结构,以便存储更多有效的数据,它会根据对象本身的状态复用自己的存储空间,也就是说,Mark Word会随着程序的运行发生变化,变化状态如下 (32位虚拟机):
在这里插入图片描述
其中轻量级锁和偏向锁是Java 6 对 synchronized 锁进行优化后新增加的,稍后我们会简要分析。这里我们主要分析一下重量级锁也就是通常说synchronized的对象锁,锁标识位为10,其中指针指向的是monitor对象(也称为管程或监视器锁)的起始地址。每个对象都存在着一个 monitor 与之关联。在Java虚拟机(HotSpot)中,monitor是由ObjectMonitor实现的,其主要数据结构如下(位于HotSpot虚拟机源码ObjectMonitor.hpp文件,C++实现的),省略部分属性

ObjectMonitor() {
    _count        = 0; //记录数
    _recursions   = 0; //锁的重入次数
    _owner        = NULL; //指向持有ObjectMonitor对象的线程 
    _WaitSet      = NULL; //调用wait后,线程会被加入到_WaitSet
    _EntryList    = NULL ; //等待获取锁的线程,会被加入到该列表
}

在这里插入图片描述
注意这里的_entrylist和WaitSet,wait线程是在一个set里,这会不会notify随机唤醒对应起来。

结合线程状态解释一下执行过程。

  1. 新建(New):新建后尚未启动的线程
  2. 阻塞(Blocked):线程被阻塞,等待着获取monitor lock进入同步代码块或同步方法。“阻塞状态”与“等待状态”的区别是:“阻塞状态”在等待获取着一个排他锁,这个事件将在另外一个线程放弃这个锁的时候发生
  3. 运行(Runable):Runnable包括了操作系统线程状态中的Running和Ready
  4. 无限期等待(Waiting):不会被分配CPU执行时间,进入等待状态的线程要等待被其他线程显式的唤醒比如notify()或notifyAll()。调用没有设置Timeout参数的Object.wait()方法、没有设置超时时间的Thread.join()方法、ockSupport.park()方法会使线程进入Waiting状态。
  5. 限期等待(Timed Waiting):不会被分配CPU执行时间,不过无需等待其他线程显示的唤醒,在一定时间之后会由系统自动唤醒。例如调用Thread.sleep()方法,设置超时时间的Object.wait(long、Thread.join(long) 等
  6. 结束(Terminated):线程结束执行

在这里插入图片描述

对于一个synchronized修饰的方法(代码块)来说:

  1. 当多个线程同时访问该方法,那么这些线程会先被放进_EntryList队列,此时线程处于blocked状态
  2. 当一个线程获取到了对象的monitor后,那么就可以进入running状态,执行方法。此时,ObjectMonitor对象的/_owner指向当前线程,_count加1表示当前对象锁被一个线程获取
  3. 当running状态的线程调用wait()方法,那么当前线程释放monitor对象,进入waiting状态,ObjectMonitor对象的/_owner变为null,_count减1,同时线程进入_WaitSet队列,直到有线程调用notify()方法唤醒该线程,则该线程进入_EntryList队列,竞争到锁再进入_Owner区
  4. 如果当前线程执行完毕,那么也释放monitor对象,ObjectMonitor对象的/_owner变为null,_count减1

由此看来,monitor对象存在于每个Java对象的对象头中(存储的是指针),synchronized锁便是通过这种方式获取锁的,也是为什么Java中任意对象可以作为锁的原因,同时也是notify/notifyAll/wait等方法存在于顶级对象Object中的原因

synchronized如何获取monitor对象?

synchronized修饰代码块

public class SyncCodeBlock {
    public int count = 0;
    public void addOne() {
        synchronized (this) {
            count++;
        }
    }
}
javac SyncCodeBlock.java
javap -v SyncCodeBlock.class

反编译的字节码如下

  public void addOne();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=3, args_size=1
         0: aload_0
         1: dup
         2: astore_1
         3: monitorenter // 进入同步方法
         4: aload_0
         5: dup
         6: getfield      #2                  // Field count:I
         9: iconst_1
        10: iadd
        11: putfield      #2                  // Field count:I
        14: aload_1
        15: monitorexit // 退出同步方法
        16: goto          24
        19: astore_2
        20: aload_1
        21: monitorexit // 退出同步方法
        22: aload_2
        23: athrow
        24: return
      Exception table:

可以看到进入同步代码块,执行monitorenter指令,退出同步代码块,执行monitorexit指令,可以看到有2个monitorexit指令,第一个是正常退出执行的,第二个是当异常发生时执行的

synchronized修饰方法

public class SyncMethod {
    public int count = 0;
    public synchronized void addOne() {
        count++;
    }
}

反编译的字节码如下

  public synchronized void addOne();
    descriptor: ()V
    // 方法标识ACC_PUBLIC代表public修饰,ACC_SYNCHRONIZED指明该方法为同步方法
    flags: ACC_PUBLIC, ACC_SYNCHRONIZED
    Code:
      stack=3, locals=1, args_size=1
         0: aload_0
         1: dup
         2: getfield      #2                  // Field count:I
         5: iconst_1
         6: iadd
         7: putfield      #2                  // Field count:I
        10: return
      LineNumberTable:

我们并没有看到monitorenter和monitorexit指令,那是怎么来实现同步的呢?
可以看到方法被标识为ACC_SYNCHRONIZED,表明这是一个同步方法

synchronized锁的升级

在Java早期版本中,synchronized属于重量级锁,效率低下,因为操作系统实现线程之间的切换时需要从用户态转换到核心态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高。庆幸的是在Java 6之后Java官方对从JVM层面对synchronized较大优化,所以现在的synchronized锁效率也优化得很不错了,Java 6之后,为了减少获得锁和释放锁所带来的性能消耗,引入了偏向锁和轻量级锁,简单介绍一下

synchronized锁有四种状态,无锁,偏向锁,轻量级锁,重量级锁,这几个状态会随着竞争状态逐渐升级,锁可以升级但不能降级,但是偏向锁状态可以被重置为无锁状态

偏向锁

为什么要引入偏向锁?

因为经过HotSpot的作者大量的研究发现,大多数时候是不存在锁竞争的,常常是一个线程多次获得同一个锁,因此如果每次都要竞争锁会增大很多没有必要付出的代价,为了降低获取锁的代价,才引入的偏向锁。

偏向锁原理和升级过程

当线程1访问代码块并获取锁对象时,会在java对象头和栈帧中记录偏向的锁的threadID,因为偏向锁不会主动释放锁,因此以后线程1再次获取锁的时候,需要比较当前线程的threadID和Java对象头中的threadID是否一致,如果一致(还是线程1获取锁对象),则无需使用CAS来加锁、解锁;如果不一致(其他线程,如线程2要竞争锁对象,而偏向锁不会主动释放因此还是存储的线程1的threadID),那么需要查看Java对象头中记录的线程1是否存活,如果线程1存活且仍需要持有这个锁,那么暂停当前线程1,撤销偏向锁,升级为轻量级锁。如果线程1没有存活或者不再需要这个锁,那么锁对象被重置为无锁状态,其它线程(线程2)可以竞争将其设置为偏向锁。

在这里插入图片描述

轻量级锁

为什么要引入轻量级锁?

轻量级锁考虑的是竞争锁对象的线程不多,而且线程持有锁的时间也不长的情景。因为阻塞线程需要CPU从用户态转到内核态,代价较大,如果刚刚阻塞不久这个锁就被释放了,那这个代价就有点得不偿失了,因此这个时候就干脆不阻塞这个线程,让它自旋这等待锁释放。

轻量级锁原理和升级过程

线程1获取轻量级锁时会先把锁对象的对象头MarkWord复制一份到线程1的栈帧中创建的用于存储锁记录的空间(称为DisplacedMarkWord),然后使用CAS把对象头中的内容替换为线程1存储的锁记录(DisplacedMarkWord)的地址;

如果在线程1复制对象头的同时(在线程1CAS之前),线程2也准备获取锁,复制了对象头到线程2的锁记录空间中,但是在线程2CAS的时候,发现线程1已经把对象头换了,线程2的CAS失败,那么线程2就尝试使用自旋锁来等待线程1释放锁。 自旋锁简单来说就是让线程2在循环中不断CAS,但是如果自旋的时间太长也不行,因为自旋是要消耗CPU的,因此自旋的次数是有限制的,比如10次或者100次。如果自旋次数到了线程1还没有释放锁,或者线程1还在执行,线程2还在自旋等待,这时又有一个线程3过来竞争这个锁对象,那么这个时候轻量级锁就会膨胀为重量级锁。重量级锁把除了拥有锁的线程都阻塞,防止CPU空转。

几种锁的优缺点
在这里插入图片描述

synchronized锁的最佳实践

  • 错误的加锁姿势1

    synchronized (new Object())
    

每次调用创建的是不同的锁,相当于无锁

  • 错误的加锁姿势2

    private Integer count;
    synchronized (count)
    
    

    String,Integer 都用了享元模式,即值在一定范围内对象是同一个。所以看似是用了不同的对象,其实用的是同一个对象。会导致一个锁被多个地方使用

  • 正确的加锁姿势

    // 普通对象锁
    private final Object lock = new Object();
    // 静态对象锁
    private static final Object lock = new Object();	
    

最后总结一波,synchronized和ReentrantLock的异同

既然有了synchronized,为啥还要提供Lock接口呢?也许你会说Lock接口比synchronized性能高。在jdk1.5之前确实如此,但是在jdk1.6之后,两者性能差不多了。

  1. ReentrantLock支持的功能更多,如支持非阻塞的方式获取锁,能够响应中断等,而synchronized不行;ReentrantLock可以是公平锁或者非公平锁,而synchronized只能是非公平锁
  2. ReentrantLock需要手动显示的获取和释放锁,一定记得在finally里手动释放锁,防止发生异常时没有释放锁;而synchronized会隐式的释放锁,发生异常也会自动释放锁,不会导致死锁的发生
  3. synchronized和ReentrantLock都是可重入锁
中职网络安全2021年国赛Wireshark流量分析题目解析 中职网络安全Wireshark流量分析题目解析 阅读详情

相关推荐

GIS坐标系转换以及空间校正和地理配准

许多小伙伴都对坐标系,投影这类问题迷迷糊糊,我之前也一样,现在总结一下。 坐标系的转换1.为什么要进行坐标系的转换?2. 不同坐标系的介绍1.地理坐标系我国常见的地理坐标(1).北京54坐标系(2).西安80坐标系(3).WGS-84坐标系(4).大地2000坐标系2.投影坐标系我国常用的投影坐标系(1) UTM投影(2) 高斯-克吕格投影(3) 兰伯特投影(4) 阿尔伯斯投影投影坐标系的选择3. 坐标系的转换1.已知坐标系之间的转换1.1 两坐标系的参考椭球相同1.2 两坐标系的参考椭球不一致,但是GIS

m0_47258611的博客 8912

Synchronized的底层实现原理(原理解析,面试必备)

synchronize的底层实现原理和monitor的实现机制

weixin_42460087的博客 3万+

发那科FOCAS 1/2文档——核心库文件

在开始开发前,明确目标 CNC 的具体型号、连接方式(HSSB/TCP/IP)、软件版本和配置(如轴数、程序号位数),并据此正确配置开发环境和编译选项。开发时需要包含相应的头文件。这是开发跨平台应用时需要特别注意的地方。这是开发应用时必须了解的核心文件。

snailiot的博客 1019

synchronized 的底层原理

synchronized 的底层原理

激流丶的博客 7440

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search 发表位置 ECCV 2020 摘要 作者提出了一种基于得分的黑盒Square attack,该模型不依赖于模型的局部梯度信息,因此可以绕过梯度隐藏防御攻击。Square Attack是一种随机搜索方法,它在随机位置选择局部的方形更新,使得每次迭代时扰动近似位于可行集的边界。 背景 当涉及到对安全至关重要的机器学习应用时,对抗性的例子尤其值得

yayayamaomaoya的博客 2492

数值天气预报期末复习

数值天气预报期末复习

m0_60394632的博客 7678

一文详解synchronized底层实现原理

synchronized底层实现基础知识并发编程的三个问题可见性(1)什么是可见性?(2)实例演示(3)保证可见性方式一:使用`synchronized`加锁方式二:`volatile`修饰共享变量原子性(1)什么是原子性?(2)实例演示(3)保证原子性有序性(1)什么是有序性(2)实例演示(3)`as-if-serial`语义(4)保证有序性`Java`内存模型:`JMM(JavaMemoryModel)`(1)什么是`JMM`?(2)具体实现`计算机的内存模型`:现在开始聊一下`JMM`:规定关系作用.

多回头看一看 4182

3步搞定专利数据爬取:用Selenium绕过国家知识产权局反爬(附完整代码)

本文详细介绍了3种高效获取专利数据的技术方案,重点解析了使用Selenium绕过国家知识产权局反爬的实战方法,并提供了完整代码示例。文章还探讨了Requests+lxml轻量级方案和混合技术策略,帮助开发者根据需求选择最佳数据爬取方案,特别适合需要专利统计数据的开发者参考。

weixin_29029995的博客 1108

说一下synchronized底层实现原理?_死磕synchronized关键字底层原理

前言作为Java程序员,我们都知道在多线程的情况下,为了保证线程安全,经常会使用synchronized和Lock锁。Lock锁之前写过一篇《不得不学的AQS》,已经详细讲解过Lock锁的底层原理。这次我们讲一下日常开发中常用的关键字synchronized,想要用得好,底层原理必须要搞明白。synchronized是JDK自带的一个关键字,在JDK1.5之前是一个重量级锁,所以从性能上...

weixin_29725791的博客 2431

GD32F130之USART多机通信

简介 在多机通信中,一个从机应该只接收它需要接收的数据,且只应该在它需要接收数据时才检测串口。而始终接收RX线上的数据对从机来说是一种负担。 多机通信硬件设计 远距离方案:RS485 板级方案: 静默模式 静默模式有什么作用? 答:如果 USART 处于静默模式,所有的接收状态标志位将不会被置位。 如何进入静默模式? 答:软件可以通过将 USART_CMD 寄存器中MMCMD 位置 1 使 USART 进入静默模式。 如何从静默模式中唤醒? 答:有两种方式可选,①检测到总线

luliplus的博客 299

Codex 100个真实案例 - 用AI做在线考试系统(自动组卷+防作弊)

本案例使用 Codex 从零搭建一个功能完整的在线考试系统。涵盖题库管理(单选/多选/判断/填空)、智能随机组卷、考试倒计时、自动判分、成绩统计分析、以及多维度防作弊机制(切屏检测、禁止复制粘贴、IP限制等)。前端使用 Vue 3 + Element Plus 构建考试界面,后端使用 Node.js + Express + MySQL 提供 API 服务。全程用自然语言驱动 Codex 完成开发,最终交付一个可直接部署的在线考试平台。

yueyeguzhuo的专栏 77

Synchronized底层核心原理

本篇文章是关于并发编程中Synchronized锁的底层核心原理知识记录,由于篇幅原因,下篇文章将介绍各种锁的优化原理。

小威的博客 8692

【基础演练】Playwright 极简复习:作为 AI-RPA 底座的 Playwright 核心用法

摘要: 2026年,Playwright已从测试工具升级为AI-RPA标准执行底座,周下载量超3300万,被browser-use等AI Agent项目广泛采用。其核心架构通过Playwright Server实现多浏览器协议适配,支持远程连接与高并发隔离(BrowserContext)。自动等待机制显著提升稳定性,但高频交互场景可能需直接使用CDP协议。Playwright凭借跨浏览器兼容性、轻量级隔离和微软官方支持,成为测试、RPA和AI Agent领域的事实标准,未来将主导对话式自动化市场。

ZDQ58818的博客 233

synchronized 底层实现原理?

synchronized 底层实现原理? 一、作用 确保线程互斥的访问同步代码 保证共享变量的修改能够及时可见 有效解决重排序问题 二、用法 修饰普通方法 修饰静态方法 修饰代码块 三、原理 同步代码块是通过 monitorenter 和monitorexit 指令获取线程的执行权 同步方法通过加ACC_SYNCHRONIZED 标识实现线程的执行权的控制 测...

ConstXiong 1万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

synchronized底层原理

synchronized底层原理 我们都知道synchronized可以让代码同步,所谓同步代码就是在同一时刻只能有一个线程执行这段代码。 synchronized可以锁对象,例如 pubilc class Demo{ private Object object; public Demo (Object obj){ this.obj = obj; } pubilc void method(){ synchronized(obj){

weixin_44900773的博客 420

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Synchronized底层原理深入解析

synchronized是Java中的一个关键字,用于保证多线程访问共享资源时的互斥性。它可以用在方法或代码块上,用于加锁某个对象或者类,避免多个线程同时访问临界区代码,造成数据不一致或线程安全问题。为了减少锁竞争带来的性能瓶颈,Java提供了一些优化技术和策略来减少锁的粒度、提升锁的效率,从而提高多线程程序的性能。常见的优化策略有减少锁的粒度锁粗化和锁消除。特性主要功能显式锁,提供更多控制,如尝试锁、定时锁、可中断锁等用于线程等待某些任务完成后继续执行互斥控制,确保对共享资源的访问线程协调。

一碗黄焖鸡三碗米饭的博客 1553

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

三面阿里,最后问了Synchronized底层原理

一谈到多线程安全问题,我们总会想到加锁可以解决线程安全的问题,JAVA提供的锁有两个,一个是synchronized关键字,另外一个就是lock类。在JDK1.6之前,synchronized是一个重量级锁,使用不方便,性能低下。在JDK1.6之后,synchronized进行了很大的优化,加入了偏置锁、轻量级锁、自旋锁等,大大提高了synchronized的性能。现在一起看看Synchroniz...

qq_36526036的博客 5003

Synchronized底层原理

是 Java 中用于实现线程同步的一个关键字,它通过加锁机制来保证多线程环境下共享资源的线程安全。虽然我们在应用中使用时只需关注其功能,但它的底层原理其实涉及到 JVM 的同步机制和操作系统层面的原子操作。理解的底层原理,有助于我们深入理解它的性能开销、优化方式及其内部工作机制。

m0_69529796的博客 821

深入 synchronized 底层原理

synchronized 的使用 synchronized 关键字是 Java 中锁的一种实现,常用于解决并发问题。 在 Java 中每个对象都可以作为锁。 synchronized 共有三种用法。 修饰静态方法,锁是当前对象的 Class 对象。 修饰普通方法,锁是当前实例对象。 修饰代码块,锁是 synchronized 括号里的对象。 synchronized 原理 利用反编译的来查看加...

xj13829061922的博客 1070

Java 的 synchronized 底层原理

如果该对象的锁计数器为 0 ,则尚未被其他线程持有,则当前线程可以成功获取锁,计数器+1,从而实现可重入性,并继续执行同步代码块。偏向锁: 当一个线程第一次获取锁时,JVM 会将该线程标记为“ 偏向 ”状态,后续若该线程再获取该锁,无需进行额外同步过程。释放锁时同理,可重入锁的,每一次退出方法,就会将status减1,直至status的值为0,最后释放该锁。重量级锁: 当 CAS 失败无法获取锁,锁会升级为重量级锁,线程会被挂起,直到锁被释放。如果锁已被其他线程持有,则当前线程将会被阻塞,直到锁被释放。

欢迎来到空说的博客 1308

通俗易懂synchronized的底层原理

每个对象都是一个监视器锁(monitor),当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者。**指令执行时,monitor的进入数减1,如果减1后进入数为0,那线程退出monitor,不再是这个monitor的所有者。这是因为静态成员不属于任何一个实例对象,归整个类所有,不依赖于类的特定实例,被类的所有实例共享。

qq_44373419的博客 917

Synchronized底层实现原理

Synchronized底层实现原理

在路上 266

彻底理解Synchronized底层实现原理

这篇文章会记录Synchronized的常用使用场景与Synchronized的底层实现原理。虽然我们平时经常会在多线程中使用Synchronized关键字,但可能对于这个我们很熟悉的关键字的底层到底是怎样实现的没有过多关注。作为开发者,既然使用到了,可以试着去一步一步揭开下它的底层面纱。 为什么要使用Synchronized? 首先我们来看下这段代码 public class Demo { private static int count=0; public /*synch.

疯一样的女子 4594

synchronized锁的底层原理

需要注意的是,锁的升级是逐级升级的过程,而不是直接跳跃到最高级别的锁。锁的升级过程是由JVM自动管理的,根据线程的竞争情况和访问模式来判断是否需要升级锁的状态。在上锁的过程中,如果有其他线程也来抢锁,则进入EntryList 进行阻塞,当获得锁的线程执行完了,释放了锁,就会唤醒EntryList 中等待的线程竞争锁,竞争的时候是非公平的。来决定当前线程是否获得了锁,如果某一个线程获得了锁,在没有释放锁之前,其他线程是不能或得到锁的。类的Class对象的监视器锁,并执行方法体中的代码。其他线程如果尝试调用。

apple_51673523的博客 4389

Synchronized的底层实现原理

Synchronized的底层实现原理 如果我们要想了解synchronized底层实现原理,那么不妨先来了解了解对象在堆中的存储结构 java对象在堆中的存储结构分为三个部分,分别为对象头、实例变量和填充字节。 对象头里面主要包含MarkWord和Klass Point类型指针,MarkWord里面存储的是对象自身的运行时数据(包含了Hashcode、GC分带年龄、锁状态标记、线程持有的锁等等...

zm357561003的博客 766
上一篇: MySql数据库索引底层数据结构
下一篇: java代码从编译到加载执行的过程
余生之君
博客等级 码龄10年 246粉丝 98原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值