JVMの堆、栈内存存储

1、JVM栈的数据存储

        通过前面的学习,我们知道,将源代码编译成字节码文件后,JVM会对其中的字节码指令解释执行,在解释执行的过程中,又利用到了栈区的操作数栈局部变量表两部分。

        而局部变量表又分为一个个的槽位,通常第0个槽位存放实例方法的this。而每个槽位的空间大小是根据不同虚拟机决定的:

  • 32位虚拟机:32位,4个字节。
  • 64位虚拟机:64位,8个字节。

        在Java中有八大基本数据类型,它们在中占用的字节数都是不同的,如下表所示:

        其中内存占用最多的是longdouble类型,8个字节。

        它们在局部变量表中,需要占用两个槽位。如果这样说,很多人会有疑问,"每个槽位的空间大小是根据不同虚拟机决定的",如果是32位虚拟机,每个槽位只有4个字节,占用两个槽位是没有问题的。但是如果是64位虚拟机呢?每个槽位有8个字节,按理说一个槽位就可以放下了,为什么还是需要占用两个槽位?

        原因在于,Java语言的跨平台特性。局部变量表是在编译期间就确定下来的,无法得知将来JVM会在何种环境下解释执行字节码指令。所以为了保证通用性,统一按照64位虚拟机进行考虑。并且虽然longdouble类型占用了两个槽位共16个字节,实际上它的高8字节是没有被使用的。

        栈中的数据要保存到堆上&堆中加载到栈上需要如何实现?

        在编译成的字节码文件中,所有占用了一个槽位的数据类型都是被当做了int执行(iconst),int默认占有4个字节,也就是在栈上这些都默认占有了4个字节。

        但是在堆上,它们实际有的只占有了1个字节,有的占有了2个字节。所以栈中的数据要保存在堆上,需要进行截取,堆中的数据加载到栈上则反之。


         在进行过程分析之前,首先要明白两个概念,符号位高(低)位

  • 符号位:符号位是在计算机中用来表示数值的正负的特殊位。通常情况下,一个整数的符号位是用来表示该整数是正数还是负数的。在计算机中,符号位通常是由整数类型的最高位(最左侧的位)来表示的,其中 0 表示正数,1 表示负数。例如,在一个有符号的 8 位整数中,如果最高位是 0,则该整数被解释为正数;如果最高位是 1,则该整数被解释为负数。
  • 高低位:通常是指在计算机中用于表示数字的二进制位的位置。在一个多字节的数据类型(比如整数或者浮点数)中,位被分为高位低位两部分。高位是数据中权值最高的位,通常位于数据的最左侧。在有符号整数中,高位通常用于表示符号位(0 表示正数,1 表示负数)。在无符号整数中,高位用于表示最大的数值。低位是数据中权值最低的位,通常位于数据的最右侧。低位存储着数据的最小的权值。

        堆中的数据加载到栈上时,也要考虑符号位的问题。booleanchar类型没有符号位,直接高位补0即可,byteshort有符号位,低位直接复制,高位负则补1,非负补0:

        栈中的数据要保存在堆上 ,需要将高位截取掉。而boolean类型只取低位的最后一位。

2、JVM对象在堆上的存储

         对象在堆中的内存布局,分为对象头对象数据两部分,对象头中又有标记字类型指针。如果是数组对象类型,对象头中额外保存了数组的容量

        其中标记字 的结构,在64位和32位虚拟机中都不一样,其中64位虚拟机又分为是否进行了指针压缩

这一块详见:http://t.csdnimg.cn/8D7DI

        我们也可以通过JoL jar包中提供的方法打印出这一块的信息:

        在打印出的信息中,我们可以发现,引用数据类型是排在最后的,并且在类的定义中,是long变量在前,int变量在后。但是打印出的对象头信息中,两者的顺序发生了交换,原因在于,每个属性的偏移量必须是字段长度的整数倍。在这个案例中,假如long变量在前,那么它的OFFSET和SIZE 就会变成12和8,不满足整数倍的条件,所以会做出调整。这就是内存对齐

        而内存对齐的主要目的是为了解决在并发环境下cpu缓存失效的情况。

        简单来说,在一个缓存行中,可能存在多个实例的缓存。当其中一个实例的缓存失效需要更新时,会让整个缓存行都失效。从而影响到缓存行中的其他对象。

        内存对齐后,可以理解成同一个缓存行不会存有不同类型的对象,即使某个对象的缓存失效,也不会影响其他的对象:


        上面也提到过指针压缩的概念。什么是指针压缩?

        指针压缩是一种优化技术,用于减小程序中指针所占用的内存空间。

        在64位系统中,一个指针通常需要8个字节。但在许多情况下,指针实际指向的地址并不需要使用那么多的位来表示,因为程序的内存地址空间可能不会达到8字节指针所能表示的范围。

        指针压缩技术利用这一点,通过降低指针所占用的位数来节省内存空间。这通常是通过将指针存储为较小的数据类型(比如32位系统中的4字节)来实现的,因为在大多数情况下,程序的内存地址空间并不会达到需要用到更多位表示的程度。

        指针压缩的一个常见实现方式是使用对象偏移量(Object Offset)来表示指针。在这种情况下,指针不再直接存储对象的内存地址,而是存储对象相对于某个基准地址(如堆的起始地址)的偏移量。通过这种方式,可以使用较少的位数来表示指针,从而节省内存空间。

        例如下图,左边的部分没有进行指针压缩,右边的部分进行了指针压缩。

        没有进行指针压缩时,当前对象的内存地址是8,并且占用了8个字节。进行了内存压缩后,指针中不存放真实的地址,而是存放编号(偏移量)。

 

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

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

相关文章

前端将DOM元素导出为图片

前端工作中经常会用到把一些元素导出,比如表格,正好项目有遇到导出为excel和导出为图片,就都封装实现了一下,以供其他需求的开发者使用: 1.导出为文档 这个说白了就是下载的功能,传过去检索参数&#xff…

MySQL——事务补充

十一、RR和RC的本质区别 select * from 表名 (lock in share mode) #当不加共享锁时,说明此时进行的是快照读,加了共享锁则进行的是当前读;​ 当进行快照读的时候才会形成read view结构; ​ read view形成的时机不同&#xff0c…

超分辨重建——SRGAN网络训练自己数据集与推理测试(详细图文教程)

💪 专业从事且热爱图像处理,图像处理专栏更新如下👇: 📝《图像去噪》 📝《超分辨率重建》 📝《语义分割》 📝《风格迁移》 📝《目标检测》 📝《暗光增强》 &a…

标题:Go语言中的YAML魔法:轻松配置你的环境

摘要: 本文将介绍如何在Go语言项目中使用YAML文件来管理配置,包括如何读取YAML文件以及如何在代码中解析和使用这些配置。 正文: 在编程世界中,配置管理是每个项目都必须面对的问题。对于Go语言项目来说,YAML文件是一…

【TB作品】msp430f149单片机,读取ds18b20温度,显示到数码管,串口发送温度到电脑

功能 msp430f149单片机 读取ds18b20温度,显示到数码管,串口发送温度到电脑 部分程序 /************************************************* * 程序功能:用DS18B20测量室温并在数码管上显示。 * --------------------------------------…

计算机视觉与模式识别实验2-1 角点检测算法(Harris,SUSAN,Moravec)

文章目录 🧡🧡实验流程🧡🧡Harris算法SUSAN算法Moravec算法 🧡🧡全部代码🧡🧡 🧡🧡实验流程🧡🧡 Harris算法 Harris算法实现步骤&…

【面试题-015】DockerFile中CMD和ENTRYPOINT指令有什么区别

文章目录 DockerFile中CMD和ENTRYPOINT指令有什么区别docker容器是怎么实现的docker的联合文件系统是什么 简单说下docker如何实现网络通信 DockerFile中CMD和ENTRYPOINT指令有什么区别 在Docker中,CMD和ENTRYPOINT指令都是用来指定容器启动时运行的命令。它们之间…

《尚上优选》项目Bug记录

写在前面 本项目为该系列第二个项目,有一些问题如果没有在本文摘录,可以到 《云尚办公》项目 BUG记录 中查找是否有类似的解决方案。 (2024.3.24以下) (P11) 管理端前端node20版本启动报OpenSSL错误 经典问题,把we…

PostgreSQL设置自增主键

PostgreSQL设置自增主键 1 创建一个序列 CREATE SEQUENCE id_seq START 1; 2将指定字段修改为对应的数据类型序列 alter table test alter column id set default nextval(id_seq);test , id , id_seq

如何快速定位到影响mysql cpu飙升的原因——筑梦之路

通常我们只需要执行show processlist 进行查看,一般执行时间最长的SQL八九不离十就是罪魁祸首,但当show processlist的输出有近千条,那么很难第一眼就发现有问题的SQL,那么如何快速找到呢?其实也非常简单。我们知道mys…

JS面试题:什么是原型和原型链

一、原型 函数都有prototype属性,称之为原型,也称为原型对象原型 1.可以放一些属性和方法,共享给实例对象使用 2.原型可以做继承 二、原型链: 对象都有proto 属性,这个属性指向它的原型对象,原型对象也是对也有 proto 属性,指向原型对象的原型对象,这样一…

drand- 随机数获取和验证

文章目录 一、drand- 随机数获取和验证1. 什么是drand2. drand组织3. 获取公开随机性(Randomness)4. 获取私有随机性(Randomness)5. 通过http端点 获取6. 随机数验证 二、部署安装1. 通过源码安装2. 使用3. 创建Drand部署 三、其他…

论文摘要一般要写些什么内容?

论文摘要通常需要包含以下几个关键内容: 研究背景与目的:简要介绍研究的背景信息,包括研究领域的重要性、当前的研究现状以及存在的问题。然后,清晰地阐述研究的目的、研究问题或研究假设,让读者明白研究的出发点和意图…

推荐一个图片识别的llama3微调版本 清华面壁项目

水一篇: MiniCPM-V是面向图文理解的端侧多模态大模型系列。该系列模型接受图像和文本输入,并提供高质量的文本输出。自2024年2月以来,我们共发布了4个版本模型,旨在实现领先的性能和高效的部署,目前该系列最值得关注的…

工业4.0利器:MES系统

工业4.0利器:MES系统 😄生命不息,写作不止 🔥 继续踏上学习之路,学之分享笔记 👊 总有一天我也能像各位大佬一样 🏆 博客首页 怒放吧德德 To记录领地 🌝分享学习心得,…

2024/6/3随笔

上周二又出差了,出差三天,跟公司里的一个年轻小哥一起去合肥,他教我怎么操作BI机器,就是ATE测试里面的老化测试,输入命令运行机器那种,说实话,他们写的这个脚本命令没有我自己写的uoskit写的好&…

Java如何实现pdf转base64以及怎么反转?

问题需求 今天在做发送邮件功能的时候,发现邮件的附件部分,比如pdf文档,要求先把pdf转为base64,邮件才会发送。那接下来就先看看Java 如何把 pdf文档转为base64。 两种方式,一种是通过插件 jar 包的方式引入&#xf…

英语学习笔记31——Where‘s Sally?

Where’s Sally? Sally在哪? 词汇 Vocabulary garden /ˈɡɑːrdn/ n. 花园,院子(属于私人) 区别:park n. 公园(公共的) 例句:我的花园非常大。    My garden is very big. 搭…

【linux-imx6ull-设备树点灯】

目录 1. 设备树简介1.1 编译-引用1.2 设备树文件结构1.3 设备树节点介绍1.3.1 特殊节点chosen 1.4 节点内容追加 2. 设备树常用OF操作函数2.1 节点寻找类2.2 属性提取类2.3 其它常用类 4. 设备树下LED实验4.1 实验简介4.2 添加LED设备节点4.3 获取设备节点并提取属性4.3.1 获取…

深度学习-05-反向传播理论知识

深度学习-05-反向传播理论知识 本文是《深度学习入门2-自製框架》 的学习笔记,记录自己学习心得,以及对重点知识的理解。如果内容对你有帮助,请支持正版,去购买正版书籍,支持正版书籍不仅是尊重作者的辛勤劳动&#xf…