四、JVM-对象内存模型

news2025/1/17 9:02:11

Java对象内存模型

一个Java对象在内存中包括3个部分:对象头、实例数据和对齐填充

image.png

数据 内存 – CPU 寄存器 -127 补码 10000001 - 11111111 32位的处理器

一次能够去处理32个二进制位 4字节的数据 64位操作系统 8字节 2的64次方的寻址空间

指针压缩技术 JDK1.6出现的 开启了指针压缩 什么时候指针压缩会无效 ??

超过32G指针压缩无效

16499221260943015043ffy

小端存储 :便于数据之间的类型转换,例如:long类型转换为int类型时,高地址部分的数据可以直接截掉。

大端存储 :便于数据类型的符号判断,因为最低地址位数据即为符号位,可以直接判断数据的正负号。

java中使用的是大端存储。

内存模型设计之–Class Pointer

句柄池访问:

image.png

直接指针访问对象图解:

image.png

区别:

句柄池:

使用句柄访问对象,会在堆中开辟一块内存作为句柄池,句柄中储存了对象实例数据(属性值结构体) 的内存地址,访问类型数据的内存地址(类信息,方法类型信息),对象实例数据一般也在heap中开 辟,类型数据一般储存在方法区中。

优点 :reference存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为) 时只会改变句柄中的实例数据指针,而reference本身不需要改变。

缺点 :增加了一次指针定位的时间开销。

直接访问:

直接指针访问方式指reference中直接储存对象在heap中的内存地址,但对应的类型数据访问地址需要 在实例中存储。

优点 :节省了一次指针定位的开销。

缺点 :在对象被移动时(如进行GC后的内存重新排列),reference本身需要被修改

内存模型设计之–指针压缩

指针压缩的目的:

  1. 为了保证CPU普通对象指针(oop)缓存
  2. 为了减少GC的发生,因为指针不压缩是8字节,这样在64位操作系统的堆上其他资源空间就少了。

64位操作系统中 内存 > 4G 默认开启指针压缩技术,内存**< 4G**,默认是32位系统默认不开启。
内存 > 32G 指针压缩失效。所以我们通常在部署服务时,JVM内存不要超过32G,因为超过32G就无法开启 指针压缩了。

内存 > 32G指针压缩失效的原因是:4G*8 = 32G

32位系统的CPU 最大支持2^32 = 4G ,如果是64位系统,最大支持 2^64, 但是对其填充是按照8字节进行填充,指针压缩可以理解为在32位系统在64位上面使用,因为32位系统的CPU寻址空间最大支持4G,对其填充*8 = 32G,这就是内存>32G指针压缩失效的原因。

关闭指针压缩 : -XX:-UseCompressedOops

2的32次方 4294967296字节 4G 如果现在老项目 32位操作系统 支持 4G以上的

PAE的特殊内核

我进行了指针压缩 4G 8字节对齐

内存模型设计之–对齐填充

对齐填充的意义是 提高CPU访问数据的效率 ,主要针对会存在该实例对象数据跨内存地址区域存储的情况。

例如:在没有对齐填充的情况下,内存地址存放情况如下:

image.png

因为处理器只能0x00-0x07,0x08-0x0F这样读取数据,所以当我们想获取这个long型的数据时,处理 器必须要读两次内存,第一次(0x00-0x07),第二次(0x08-0x0F),然后将两次的结果才能获得真正的数值。

那么在有对齐填充的情况下,内存地址存放情况是这样的:

image.png

现在处理器只需要直接一次读取(0x08-0x0F)的内存地址就可以获得我们想要的数据了。

当我们的策略为0时,这个时候我们的排序是 基本类型>填充字段>引用类型

当我们策略为1时,引用类型>基本类型>填充字段

策略为2时,父类中的引用类型跟子类中的引用类型放在一起 父类采用策略0 子类采用策略1,

这样操作可以降低空间的开销 ,

2.4 JVM内存模型

2.4.1 运行时数据区

上面对运行时数据区描述了很多,其实重点存储数据的是堆和方法区(非堆),所以内存的设计也着重从这两方面展开(注意这两块区域都是线程共享的)。

对于虚拟机栈,本地方法栈,程序计数器都是线程私有的。

可以这样理解,JVM运行时数据区是一种规范,而JVM内存模式是对该规范的实现

2.4.2 图形展示

一块是非堆区,一块是堆区
堆区分为两大块,一个是Old区,一个是Young区
Young区分为两大块,一个是Survivor区(S0+S1),一块是Eden区
S0和S1一样大,也可以叫From和To

image.png

16499221260943012495ffy

2.4.3 对象创建过程

一般情况下,新创建的对象都会被分配到Eden区,一些特殊的大的对象会直接分配到Old区。

我是一个普通的Java对象,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,我们在Eden区中玩了挺长时间。有一天Eden区中的人实在是太多了,我就被迫去了Survivor区的“From”区,自从去了Survivor区,我就开始漂了,有时候在Survivor的“From”区,有时候在Survivor的“To”区,居无定所。直到我18岁的时候,爸爸说我成人了,该去社会上闯闯了。于是我就去了年老代那边,年老代里,人很多,并且年龄都挺大的。

image.png

什么时候会触发Full GC?

1.之前每次晋升的对象的平均大小 > 老年代的剩余空间 基于历史平均水平

2.young GC之后 存活对象超过了老年代的剩余空间 基于下一次可能的剩余空间

3.Meta Space区域空间不足

4.System.gc();

方法区 类信息 静态变量 常量 即时编译过后的代码 运行时常量池

JDK1.7之前 Perm space 永久代 持久代 JVM自己的内存 线性整理 会增加垃圾回收的时间

JDK1.8 Meta Space 元空间 元数据区 直接内存 减少内存碎片 节省压缩时间

类的总数 常量池的大小 方法的数量 设置JVM内存 2G

16499221260943019786ffy

1.动态扩容

分配内存 1.7之前 线性分配

2.4.4 常见问题

  • 如何理解Minor/Major/Full GC
Minor GC:新生代
Major GC:老年代
Full GC:新生代+老年代
  • 为什么需要Survivor区?只有Eden不行吗?
如果没有Survivor,Eden区每进行一次Minor GC,存活的对象就会被送到老年代。
这样一来,老年代很快被填满,触发Major GC(因为Major GC一般伴随着Minor GC,也可以看做触发了Full GC)。
老年代的内存空间远大于新生代,进行一次Full GC消耗的时间比Minor GC长得多。
执行时间长有什么坏处?频发的Full GC消耗的时间很长,会影响大型程序的执行和响应速度。

可能你会说,那就对老年代的空间进行增加或者较少咯。
假如增加老年代空间,更多存活对象才能填满老年代。虽然降低Full GC频率,但是随着老年代空间加大,一旦发生Full GC,执行所需要的时间更长。
假如减少老年代空间,虽然Full GC所需时间减少,但是老年代很快被存活对象填满,Full GC频率增加。

所以Survivor的存在意义,就是减少被送到老年代的对象,进而减少Full GC的发生,Survivor的预筛选保证,只有经历16次Minor GC还能在新生代中存活的对象,才会被送到老年代。
  • 为什么需要两个Survivor区?
最大的好处就是解决了碎片化。也就是说为什么一个Survivor区不行?第一部分中,我们知道了必须设置Survivor区。假设现在只有一个Survivor区,我们来模拟一下流程:
刚刚新建的对象在Eden中,一旦Eden满了,触发一次Minor GC,Eden中的存活对象就会被移动到Survivor区。这样继续循环下去,下一次Eden满了的时候,问题来了,此时进行Minor GC,Eden和Survivor各有一些存活对象,如果此时把Eden区的存活对象硬放到Survivor区,很明显这两部分对象所占有的内存是不连续的,也就导致了内存碎片化。
永远有一个Survivor space是空的,另一个非空的Survivor space无碎片。
  • 新生代中Eden:S1:S2为什么是8:1:1?
新生代中的可用内存:复制算法用来担保的内存为9:1
可用内存中Eden:S1区为8:1
即新生代中Eden:S1:S2 = 8:1:1
现代的商业虚拟机都采用这种收集算法来回收新生代,IBM公司的专门研究表明,新生代中的对象大概98%是“朝生夕死”的
  • 堆内存中都是线程共享的区域吗?
JVM默认为每个线程在Eden上开辟一个buffer区域,用来加速对象的分配,称之为TLAB,全称:Thread Local Allocation Buffer。
对象优先会在TLAB上分配,但是TLAB空间通常会比较小,如果对象比较大,那么还是在共享区域分配。

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

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

相关文章

聚观早报 | iPhone 15 Pro系列有望成为苹果三年来最大升级

【聚观365】8月3日消息 苹果三年来最大升级 小米驰援北京河北暴雨救灾 印度要求特斯拉仿效苹果 比亚迪7月新能源车销量同比增长61% 富士康计划在印度新建两家零件工厂 苹果三年来最大升级 苹果将继续在今年9月举办一年一度的秋季新品发布会&#xff0c;届时全新的iPhone …

GC 深入(小白,对gc有一个进一步的了解)

垃圾回收器的搭配 一般固定 一般这年轻代垃圾回收器&#xff0c;老年代垃圾回收器&#xff0c;如上图搭配着使用 1.8呢默认就是最后边那哥俩 jvm调优 一个就是增加吞吐量 一个就是减少STW的时间。 三色标记算法&#xff08;理解根可达算法&#xff09; 并发的可达性分析 有…

8.2Jmeter5.1:察看结果树的响应结果乱码

【问题描述】 Jmeter察看结果树的响应结果乱码 原因&#xff1a;jmeter.properties未设置语言 【解决方案】 修改jmeter.properties的属性&#xff0c;然后重启Jmeter # The encoding to be used if none is provided (default ISO-8859-1) sampleresult.default.encodingut…

AB实验遇到用户不均匀怎么办?—— vivo游戏中心业务实践经验分享

作者&#xff1a;vivo 互联网数据分析团队 - Li Bingchao AB实验是业务不断迭代、更新时最高效的验证方法之一&#xff1b;但在进行AB实验效果评估时需要特别关注“用户不均匀”的问题&#xff0c;稍不注意&#xff0c;产出的研究结论就可能谬以千里&#xff0c;给业务决策带来…

百度搭台,千家打擂,文心杯创业大赛成投资人新宠?

“百模大战”打响&#xff0c;掀起大模型领域“创业热潮”。今年5月31日&#xff0c;百度启动“文心杯”创业大赛&#xff08;后简称“大赛”&#xff09;&#xff0c;不到1个月报名时间&#xff0c;吸引近1000个项目激烈角逐&#xff0c;在知名投资人和AI专家的权威评审和层层…

.Net6 Core Web API 配置 log4net + MySQL

目录 一、导入NuGet 包 二、添加配置文件 log4net.config 三、创建MySQL表格 四、Program全局配置 五、帮助类编写 六、效果展示 小编没有使用依赖注入的方式。 一、导入NuGet 包 ---- log4net 基础包 ---- Microsoft.Extensions.Logging.Log4Net…

go逆向符号恢复

前言 之前一直没怎么重视&#xff0c;结果发现每次遇到go的题都是一筹莫展&#xff0c;刷几道题练习一下吧 准备 go语言写的程序一般都被strip去掉符号了&#xff0c;而且ida没有相关的签名文件&#xff0c;没办法完成函数名的识别与字符串的定位&#xff0c;所以第一步通常…

HCIP——BGP反射器及联邦

BGP反射器及联邦 一、路由反射器1、路由反射器的角色2、路由反射规则3、路由反射器下的防环Originator_IDCluster_List应用举例配置方法 二、联邦1、联邦概念2、联邦的配置 路由反射器和联邦是两种专门针对IBGP水平分割设计的解决方案&#xff0c;我们依次来看下这两种技术 一…

基于 Llama2 和 OpenVINO™ 打造聊天机器人

点击蓝字 关注我们,让开发变得更有趣 作者 | 英特尔 AI 软件工程师 杨亦诚 指导 | 英特尔 OpenVINO 布道师 武卓博士 排版 | 李擎 基于 Llama2 和 OpenVINO™ 打造聊天机器人 Llama 2是 Meta 发布了其最新的大型语言模型&#xff0c;Llama2 是基于 Transformer 的人工神经网络&…

SpringCloudAlibaba之Nacos服务的发现与注册中心(一)

一&#xff1a;搭建nacos服务 在windows上搭建&#xff1a; 下载nacos &#xff0c;我在本地下载的是2.1.0 Releases alibaba/nacos (github.com)https://github.com/alibaba/Nacos/releases SpringCloudAlibaba &#xff0c;SpringCoud及Spring Boot之间版本的对应关系在以…

大麦订单生成器 大麦一键生成订单截图

后台一键生成链接&#xff0c;独立后台管理 教程&#xff1a;修改数据库config/Conn 不会可以看源码里有教程 下载程序&#xff1a;https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

ACID特性、CAP理论、BASE原则详解

一、ACID 事务&#xff08;transaction&#xff09;&#xff1a;用户定义的一系列执行SQL的操作&#xff0c;这些操作要么完全执行&#xff0c;要么都不执行。 关系型数据库中的事务具有ACID特性 原子性(Atomicity)一致性&#xff08;Consistency&#xff09;隔离性&#xf…

红外NEC通信协议

一、NEC简介 红外(Infrared&#xff0c;IR)遥控是一种无线、非接触控制技术&#xff0c;常用于遥控器、无线键盘、鼠标等设备之间的通信。IR协议的工作原理是&#xff0c;发送方通过红外线发送一个特定的编码&#xff0c;接收方通过识别该编码来执行相应的操作。 IR协议是指红外…

JDK, JRE和JVM之间的区别和联系

JDK, JRE和JVM是与Java编程语言相关的三个重要的概念&#xff0c;它们分别代表Java Development Kit&#xff08;Java开发工具包&#xff09;、Java Runtime Environment&#xff08;Java运行时环境&#xff09;和Java虚拟机&#xff08;Java Virtual Machine&#xff09;。它们…

PHP8的运算符-PHP8知识详解

运算符是可以通过给出的一或多个值&#xff08;用编程行话来说&#xff0c;表达式&#xff09;来产生另一个值&#xff08;因而整个结构成为一个表达式&#xff09;的东西。 PHP8的运算符有很多&#xff0c;按类型分有一元运算符、二元运算符、三元运算符。 一元运算符只对一…

Java类与对象详解(2)

this引用 为什么要有this引用 先来看一个日期类的例子&#xff1a; ​ public class Date {public int year;public int month;public int day;//设置日期方法public void setDay(int y, int m, int d){//这里隐藏了一个Date this参数year y;month m;day d;}public void …

广州银行信用卡中心:强化数字引擎安全,实现业务稳步增长

广州银行信用卡中心是全国城商行中仅有的两家信用卡专营机构之一&#xff0c;拥有从金融产品研发至销售及后期风险控制、客户服务完整业务链条&#xff0c;曾获“2016年度最佳创新信用卡银行”。 数字引擎驱动业务增长 安全左移降低开发风险 近年来&#xff0c;广州银行信用卡…

fetch的使用和实现跨域及与axios的区别

一、作用 和axios作用类似&#xff0c;用于请求接口。它是XMLHttpRequest的一种替代方案。 二、安装 因为fetch有兼容性问题&#xff0c;所以我们安装升级版 whatwg-fetch cnpm i whatwg-fetch -S 三、使用 四、fetch和axios的区别 1&#xff0c;fetch返回的是一个未处理…

华为OD机试真题 Java 实现【TLV格式】【2023 B卷 200分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

聚焦 TimescaleDB VS TDengine 性能对比报告,IoT 场景下全面分析写入与查询

基于第三方基准性能测试平台 TSBS&#xff08;Time Series Benchmark Suite&#xff09; 标准数据集&#xff0c;TDengine 团队在 TSBS 的 IoT 场景中&#xff0c;预设了五种规模的卡车车队基础数据集&#xff0c;在相同的 AWS 云环境下对时序数据库&#xff08;Time Series Da…