我们简单的new了一个对象,JVM都做了哪些贡献?

news2025/1/13 11:46:51

前言:大家好,我是小威,24届毕业生,在一家满意的公司实习。本篇文章是关于CAS的介绍以及在我们new对象时,Java虚拟机会为我们做些什么贡献。
本篇文章记录的基础知识,适合在学Java的小白,也适合复习中,面试中的大佬🤩🤩。
如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。
小威在此先感谢各位大佬啦~~🤞🤞
在这里插入图片描述

🏠个人主页:小威要向诸佬学习呀
🧑个人简介:大家好,我是小威,一个想要与大家共同进步的男人😉😉
目前状况🎉:24届毕业生,在一家满意的公司实习👏👏

🎁如果大佬在准备面试,可以使用我找实习前用的刷题神器哦刷题神器点这里哟
💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,我亲爱的大佬😘

以下正文开始
在这里插入图片描述

文章目录

  • 对象创建过程
    • 指针碰撞(Bump The Pointer)
    • 空闲列表(Free List)
  • 考虑线程安全问题
    • CAS失败重试(CAS内容讲解)
    • 本地线程分配缓冲

对象创建过程

当我们使用new关键字创建对象时,Java虚拟机遇到字节码new指令时,会做些什么事情呢,下面慢慢分析。

当Java虚拟机遇到new指令时,首先会检查执行这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载过,解析过和初始化过。没有的话会先执行类加载的过程。

类加载详细过程解析:

类加载检查通过之后,虚拟机会为新建的对象分配内存空间,注意,此内存空间大小在类加载完成后就已经确定好了。因此为对象分配内存空间就相当于把一块已经确定好大小的内存从Java堆中划分出来为对象分配。但是此时对于内存,还会有两种情况,因此对应这两种不太的分配方式,即“指针碰撞”和“空闲列表”。

在这里插入图片描述

指针碰撞(Bump The Pointer)

指针碰撞,顾名思义,就是指针的移动。

指针碰撞的概念为:假设Java堆中的内存是完整的,所以被使用过的(空闲的)内存被放到一边,没有使用过的内存被放到另一边,中间有一个指针,这个指针作为分界点的指示器,在为对象分配内存空间时,指针指示器会向空闲内存的方向移动一段与对象相同大小内存的距离。这种分配方式就是“指针碰撞”。

空闲列表(Free List)

空闲列表,顾名思义,就是空闲的内存在表上名列出来。

空闲列表的概念为:如果Java堆中的内存空间不是完整的,被使用过的内存和空闲的内存交织在一起,就无法使用指针碰撞的方式分配内存了,这时候,虚拟机会维护一张表,表上会记录哪些内存是空闲可用的,在为新建对象分配空间时,就会找到一个相对与新建对象足够大的空间划分给新建对象,同时更新表上的记录,这种方式被称为“空闲列表”。
在这里插入图片描述

考虑线程安全问题

上面我们就空闲(可用)空间的划分,讨论了两种为新建对象分配空间的情况。除此之外,我们还要考虑线程安全的问题,在并发的情况下,如果正在给新建对象A分配内存,另一个新建对象B也需要分配内存,此时指针还未修改,新建对象B同时使用了原来的指针分配内存,就可能出现差错。

对于这种情况,解决的方案也有两种解决方式,即CAS失败重试和本地线程分配缓存的方式。

CAS失败重试(CAS内容讲解)

首先简单介绍一下什么是CAS,CAS(Compare And Swap),从英文名来看是比较并交换的意思,顾名思义,CAS操作的确有这么两个操作。CAS是乐观锁,即在线程执行的时候不会加锁,位于UnSafe类中。

    public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);

    public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

    public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);

在这里插入图片描述

以CompareAndSwapObject方法为例(如下代码),CompareAndSwapObject方法一共有四个变量,第一个是要修改的字段对象,第二个是字段在对象内的偏移量,第三个是字段的期望值,第四个是当该字段的值和期望值相等的话,更新字段的新值。

public native boolean compareAndSwapObject(Object obj, long offset, Object expect, Object update);

那么CAS原理是什么呢,通过一个例子来解释一下。假设内存地址中有一变量S,S的值为1,此时线程1的期望值为1,线程1想要修改变量S的值为2,在线程1修改成功之前,此时线程2将S的值修改2,并且修改成功了,因此内存地址中S的值为2,线程1发现期望值和内存地址中S的值不一致,就会发生自旋现象(也就是失败重试,重新获取内存地址中的值),直到自旋成功。先会进行Compare,如果期望值和内存地址中S的值相等,再会进行Swap操作,更新内存地址中的值。

再多说一些,CAS不需要加锁,难道就是完美的吗?

其实不然,CAS操作可能会发生典型的ABA问题,就上一个例子来说,线程2将变量S的值修改为2,然后又把S的值修改为1,这相对与线程1来说,变量S的值没有发生变化,但是CAS操作也没有检测到这种情况的发生。

出现此种情况,最简单的解决方法就是在变量上加上版本号,每当变量改变一次,变量的版本号就进行更新+1,因此虽然变量的值会改变,但是通过版本号可以得知变量值是否改变过

回归到刚才的话题,可以使用CAS加上失败重试的方式保证更新操作的原子性,对分配内存空间的动作进行同步处理。
在这里插入图片描述

本地线程分配缓冲

顾名思义,基于这种方法,会用到缓冲区,即把内存分配的动作按照线程划分在不同的内存空间中进行,每个线程会在Java堆中预先分配一块内存空间,哪个线程需要分配内存,就在哪个线程的本地缓冲区里面分配,只有本地缓冲区使用完了,分配新的缓存区才需要同步锁定。这种方法叫做本地线程分配缓冲(Thread Local Allocation Buffer,即TLAB)。

等待内存分配步骤完成后,虚拟机需要将分配到的内存空间初始化为0(对象头除外)。这样才可以保证对象的实例字段在Java代码中可以不赋初值就可以直接使用,并且此时程序访问这些字段时,这些字段都是0值。

随后,Java虚拟机对对象进行一些其他的设计,才会完整地产生此对象。但是实际上,这才是构造函数阶段,并没有完成对象的创建,还需要执行Class文件中的方法,并且对象需要的其他资源和状态信息也没有构造好,此时的字段值均为0

直到对对象初始化完成后,一个真正可用的对象才算是完全的被构造出来了。

在这里插入图片描述

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起讨论🍻
希望能和诸佬们一起努力,今后进入到心仪的公司
再次感谢各位小伙伴儿们的支持🤞

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/36.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++笔试强训】第九天

🎇C笔试强训 博客主页:一起去看日落吗分享博主的C刷题日常,大家一起学习博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话:夜色难免微凉,前方必有曙光 🌞。 💦 &…

基于骨骼的动作识别:PoseConv3D

Revisiting Skeleton-based Action Recognition解读摘要1. 简介2. Related Work2.1 基于3D-CNN的rgb视频动作识别2.2 基于GCN的骨骼动作识别2.3 基于CNN的骨骼动作识别3. Framework3.1 Pose Extraction3.2 From 2D Poses to 3D Heatmap Volumes3.3 基于骨骼的动作识别3D-CNN3.3…

智能的逻辑与理性的逻辑是不同的逻辑

1.世界是由事实和价值共同组成的1.1 事实由对象、事态及其联系(如语言)构成1.2 价值是事实在实践中的作用和效果构成1.3 事实中存在着决定论,价值里包含有自由意志1.3.1 事实反映有无,价值反映好坏1.4 每一个事实都具有变价值&…

8.2 从堆中绕过SafeS.E.H

一、实验环境 操作系统&#xff1a;windows XP SP2&#xff08;关闭DEP&#xff09; 软件版本&#xff1a;VS2008&#xff08;release&#xff09;、原版OD&#xff08;实时调试&#xff09; 二、实验代码 #include <stdafx.h> #include <stdlib.h> #include <…

计算机操作系统引论(操作系统)

目录 一、操作系统的目标 二、操作系统的作用 三、操作系统的基本特性 四、操作系统的主要功能 五、操作系统的结构设计 一、操作系统的目标 操作系统&#xff08;Operating System&#xff0c;OS&#xff09;是计算机硬件的第一层软件&#xff0c;是计算机必备配置的最基…

接口自动化测试(二)—— Postman实现接口测试

其他 接口自动化测试 知识参考&#xff1a;接口自动化测试 目录 一、Postman介绍和安装 1、简介 2、安装 3、安装Postman插件newman 二、Postman基本用法 1、案例一 2、案例二 三、Postman高级用法 1、管理测试用例Collections 1.1、创建 collections 1.2、创建 用…

libusb系列-002-Windows下libusb源码编译

libusb系列-002-Windows下libusb源码编译 文章目录libusb系列-002-Windows下libusb源码编译摘要Windows下编译libusb库下载源码进入msvc目录选择对应的项目工程编译查看编译好的库文件关键字&#xff1a; vs、 编译、 Qt、 libusb、 windows内容背景&#xff1a; 最近项目终于切…

从 0 到 1 落地前端工程化

你将获得 初识&#xff1a;总结前端工程化技能图谱 了解&#xff1a;梳理前端工程化落地流程 掌握&#xff1a;搭建前端工程化基建项目 提高&#xff1a;实战前端工程化解决方案 作者介绍 JowayYoung&#xff0c;资深前端工程师&#xff0c;目前就职于网易互动娱乐事业群&…

建立私人知识网站 cpolar轻松做到1 (部署DokuWiki)

维基百科&#xff08;wiki&#xff09;相信大家都有所耳闻&#xff0c;作为全球最有名的百科知识搜索网站&#xff0c;很多不常见的知识点都能在这上面搜索到&#xff0c;而维基百科能够成功的原因&#xff0c;就是可以编辑的和修订的功能&#xff0c;让维基百科能够收到各领域…

vue学习笔记——简单入门总结(一)

Vue学习笔记 文章目录Vue学习笔记1. 学习vue的准备1.1. vue简介:1.2. vue特点:1.2.1. 组件化&#xff1a;1.2.1. 声明式&#xff1a;1.2. vue的引入1.2.1. 直接引入&#xff1a;1.2.2. 脚手架构建vue项目&#xff1a;1.2.3&#xff1a;vue开发插件安装&#xff1a;2. vue的简单…

apache服务web页面执行shell脚本

首先安装apache服务 yum -y install httpd 如下介绍两种执行的方式 方式一、url直接传参的方式 #cat /var/www/cgi-bin/shell #!/bin/sh printf "Content-Type: text/plain\n\n" your_commands_here传参的动作 http://172.16.61.119:8098/cgi-bin/shell?pwd在…

STM32使用寄存器开发底层驱动学习(USART+DMA)

目录学习资料下载任务USART的DMA功能发送数据DMA非中断模式接收USART数据。DMA中断模式接收USART数据总结学习资料下载 在本文学习中会用到如下的文档资料&#xff0c;没有的朋友先下载。 工程模板 Cortex M3权威指南&#xff08;中文&#xff09; &#xff1a;本文简称为《…

1024程序节|你知道老师上课随机点名是怎么实现的吗

个人主页&#xff1a;天寒雨落的博客_CSDN博客-C,CSDN竞赛,python领域博主 目录 前言 随机点名 搭建主体框架 简述 执行代码 添加功能 块级元素随机输出姓名 Math.random() Math.round() 按钮控制开始/结束 onclick() clearInterval() 简述 完整代码 执行结果 片…

I/O复用--浅谈epoll

我们聊了聊select和poll知道&#xff1a; 它们都是采取轮询的方式查找是否有就绪描述符。都有数据结构从用户态拷贝到内核态&#xff0c;内核态拷贝到用户态这个过程。 为了针对许多大量连接&#xff0c;高并发的的场景下大量的资源消耗&#xff0c;效率低的问题&#xff0c;这…

网络安全实战:记一次比较完整的靶机渗透

0x01信息搜集 nmap -sC -sV -p- -A 10.10.10.123 -T4 -oA nmap_friendzone访问80端口的http服务只发现了一个域名。 0x02 DNS区域传输 因为我们前面扫描的时候发现了53端口是开着一个dns服务的&#xff0c;所以尝试使用friendzoneportal.red进行axfr&#xff0c;它的具体含…

《软件测试》实验2:嵌入式软件测试实验报告

文章目录实验目的温度控制器需求文档及测试要求环境搭建实验内容温度采集处理功能测试加热棒输出电压测试散热风扇温度传感器输入接口&#xff08;Senser_JK&#xff09;控制加热棒输出接口&#xff08;Heater_JK&#xff09;控制散热风扇输出接口&#xff08;Fan_JK&#xff0…

目标检测 YOLOv5 - 模型推理预处理 letterbox

目标检测 YOLOv5 - 模型推理预处理 letterbox flyfish 版本&#xff1a;YOLOv5 6.2 假如图片大小是1080 * 1920 &#xff08;height * width &#xff09; width 1920 height 1080 当模型输入是 640 * 640时 shapes (1080, 1920), (0.33, 0.33), (0.0, 140.0) 640/ 1920…

c++11 右值引用和移动语义

文章目录1. 左值引用和右值引用2. 左值引用与右值引用比较3. 右值引用使用场景和意义3.1左值引用的使用场景3.2左值引用的短板&#xff1a;3.3 移动构造3.4 移动赋值3.5 STL中的容器3.6 右值引用引用左值及其一些更深入的使用场景分析3.7 STL容器插入接口函数也增加了右值引用版…

Springboot 使用装饰器模式,快看,它装起来了

前言 小飞棍来咯&#xff01; 本篇文章跟小飞棍一毛钱关系没有。 本篇内容&#xff1a; 就是配合实战案例介绍我们平时 在springboot项目里面 怎么去用 装饰器模式、多层装饰怎么玩。 正文 首先先说下装饰器模式是什么 官方&#xff1a; 装饰器模式&#xff08;Decorator Pa…

Python3,5行代码,制作Gif动图,太简单了。

gif动图制作1、引言2、代码实战2.1 安装2.2 代码3、总结1、引言 小屌丝&#xff1a;鱼哥&#xff0c; 你能不能帮我找一个动图&#xff0c; 小鱼&#xff1a;啥动图&#xff0c;你自己百度不就行了。 小屌丝&#xff1a;我这不是没找到吗&#xff0c; 不然我就自己来找了。 小…