Java内存结构

news2024/11/28 4:29:21

1.对象的结构

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

2.虚拟机存储数据的方式

2.1小端存储 :

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

2.2大端存储 :

便于数据类型的符号判断,因为最低地址位数据即为符号位,可以直接判断数据的正负号。(java用的)

假设存储一个变量:int i = 1; 

3.访问到对象的2种方式 

内存模型设计之–Class Pointer

3.1句柄池访问:

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

优点 :

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

缺点 :

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

3.2直接指针访问对象:(Java选用)

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

优点:

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

缺点 :

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

4.内存模型设计之–指针压缩技术

4.1指针压缩的目的:

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

64操作系统与32位操作系统的区别:

32位的处理器

一次能够去处理32个二进制位 ,也就是一次处理4字节的数据 ,2的32次方的寻址空间(4G)

64位操作系统  

 一次能够去处理64个二进制位 ,也就是一次处理4字节的数据,2的64次方的寻址空间(16G)

4.2指针压缩失效的原因

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

4.2.1失效原因

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

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

如果现在老项目    32位操作系统  支持    4G以上的内存

PAE的特殊内核

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

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

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

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

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

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

当下次有个boolean类型在进来可以直接填充到0x07中

4.3.1Java类在读取到内存时并不是安装顺序来的

可以配置参数

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

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

策略为2时,父类中的引用类型跟子类中的引用类型放在一起,其他类型父类采用策略0,子类采用策略1,这样操作可以降低空间的开销 

当一个项目中继承关系特别多的时候就可以使用策略2,由于引用类型都放在一起,GC一次就可以回收所有的父子类引用类型。

4.3.2如果父类的内存空间由于8字节的对其,导致中间有空位,子类是否可以填充?

父类的内存有空的话不可以存放子类的数据,因为父子类有内存隔离,假设放入子类数据,需要记住这个数据时子类的还是父类的,而且基本类型在GC的时候会被回收,导致子类没有数据

5. 运行时数据区

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

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

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

6.JVM内存模型

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

6.1GC 

GC的流程

如何理解Minor/Major/Full GC

Minor GC:新生代
Major GC:老年代
Full GC:新生代+老年代

对象创建过程

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

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

6.1.2区分新生代与老年代的标准 

每一次GC都会对对像的年龄进行加一,当age=15时就会进入老年代,在对象的MarkWord中会存放对象的年龄,存储这些信息的空间只有4个2进制位,也就是(0000-1111)

6.1.2.1那么为什么是年龄到15才进入老年代?

进入old区的对象越少越好,也就是age越大越好,但是根据IBM的实验数据统计,98%的对象都是活不过一次GC的,那么剩下的也就是2%,15次GC最多存活的数据也就是30%,而且2%的对象也有活不过2次GC的,综合下来15次GC活下来的也就是10%。

7.JVM承认GC的类型

7.1Partial GC 部分GC

Minor GC:新生代
Major GC:老年代

7.2Full GC 全局GC

Full GC:Young GC+Old GC+MateSpace GC

7.3什么时候会触发Full   GC?

1.之前每次晋升的对象的平均大小 >老年代的剩余空间,基于历史平均水平,本次GC后要到老年代的数据大于前面的平均大小

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

3.Meta Space区域空间不足

4.System.gc();

7.4Meta Space空间

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

设置初始化堆内存为2G,不设置的方法区的内存大小,当内存不够时会直接溢出

 给方法区设置500M的内存空间,是包含在整个Jvm内存中的,初始化堆内存即便设置1.8G,实际的内存也只会有1.5G,因为方法区的优先级高于初始化堆内存,这样1.5G就不够用,会导致启动项目直接FullGC

JDK1.8    Meta Space是方法区的实现 也叫元空间,元数据区       直接内存   减少内存碎片        节省压缩时间

MateSpace只把静态变量和字符串常量放到初始化堆内存中,其他的全部放入服务器内存中,而且当自己内存不够时就会动态扩容(权限高)

 8.GC的悲观策略

在某些情况下可以不经过GC直接进入老年代

1.当S区中相同年龄和大于这个年龄的所有对象大小,大于S区中任何一个的一半时会直接进入老年代

2.当Eden区的所有对象经过GC后,后面进来的对象大小依然无法进入Eden区时也会直接进入老年代

9.为什么需要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还能在新生代中存活的对象,才会被送到老年代。

10.为什么需要两个Survivor区?

最大的好处就是解决了碎片化。也就是说为什么一个Survivor区不行?第一部分中,我们知道了必须设置Survivor区。假设现在只有一个Survivor区,我们来模拟一下流程:
刚刚新建的对象在Eden中,一旦Eden满了,触发一次Minor GC,Eden中的存活对象就会被移动到Survivor区。这样继续循环下去,下一次Eden满了的时候,问题来了,此时进行Minor GC,Eden和Survivor各有一些存活对象,如果此时把Eden区的存活对象硬放到Survivor区,很明显这两部分对象所占有的内存是不连续的,也就导致了内存碎片化。
永远有一个Survivor space是空的,另一个非空的Survivor space无碎片。

 Eden区经过一次GC后,剩下两个对象,但是这两个对象在内存中不是连续的,这时要进来一个70M的对象,就会造成明明Eden有空间但是放不进去,这时就会放到survivor区,这样70M的对象就可以进入Eden区

如果进行一次GC是这样情况

S0 区GC后造成了2个内存不连续的对象,而且Eden中也有这种情况,这时有个70M对象要进Eden区,这时Eden区有空间却进不去,而且S0区也是有空间,但是无法接收Eden中的两个对象,这时S1就会接收S0的对象,这样70M的对象就可以进入Eden区

11.新生代中Eden:S1:S2为什么是8:1:1?

新生代中的可用内存:复制算法用来担保的内存为9:1
可用内存中Eden:S1区为8:1
即新生代中Eden:S1:S2 = 8:1:1
现代的商业虚拟机都采用这种收集算法来回收新生代,IBM公司的专门研究表明,新生代中的对象大概98%是“朝生夕死”的

12.堆内存中都是线程共享的区域吗?

JVM默认为每个线程在Eden上开辟一个buffer区域,用来加速对象的分配,称之为TLAB,全称:Thread Local Allocation Buffer。
对象优先会在TLAB上分配,但是TLAB空间通常会比较小,如果对象比较大,那么还是在共享区域分配。

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

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

相关文章

01ctfer 文件上传

01ctfer 文件上传 启动靶场 访问该地址 代码审计 <?php header("Content-Type:text/html; charsetutf-8"); // 每5分钟会清除一次目录下上传的文件 require_once(pclzip.lib.php);if(!$_FILES){echo <!DOCTYPE html> <html lang"zh">…

conan 入门指南

conan 新手入门 1 需要注意的事项2 使用 Poco 库的 MD5 哈希计算器2.1 创建源文件2.2 搜索poco conan 库2.3 获取poco/1.9.4的元数据2.4 创建conanfile.txt2.5 安装依赖2.6 创建编译文件2.7 构建和运行程序 3 安装依赖程序4 检查依赖关系5 搜索软件包6 与其他配置一起构建 该篇…

【自留地】后端 - PHP - MySQL - Nginx - Python - Java

PHP ThinkPHP6入门手册 【精选】【汇总】ThinkPHP6入门手册_tp6手册_Rudon滨海渔村的博客-CSDN博客文章浏览阅读5.4k次。安装安装Composer【win】https://getcomposer.org/Composer-Setup.exe【Linux & MacOS】curl -sS https://getcomposer.org/installer | phpmv compo…

【前端】vue3+typescript+vite+Element-Plus搭建配置初始化项目结构

给自己一个目标&#xff0c;然后坚持一段时间&#xff0c;总会有收获和感悟&#xff01; 对于我们开发人员&#xff0c;了解和熟悉新知识&#xff0c;对于vue3&#xff0c;博主是通过TA的基本结构开始&#xff0c;vue2和vue3都有javascript前端编程语言&#xff0c;到了vue3新增…

小白也想写综述(一)

前言 在选择科研方向时&#xff0c;考虑自己的兴趣和职业目标是非常重要的&#xff1a; 综述论文的价值&#xff1a;撰写综述论文&#xff0c;尤其是在深度强化学习和区块链这样的前沿技术领域&#xff0c;能够帮助建立扎实的理论基础&#xff0c;并且对整个领域有一个全面的认…

贪吃蛇、俄罗斯方块

贪吃蛇 一、创建新项目 创建一个新的项目&#xff0c;并命名。 创建一个名为images的文件夹用来存放游戏相关图片。 然后再在项目的src文件下创建一个com.xxx.view的包用来存放所有的图形界面类&#xff0c; 创建一个com.xxx.controller的包用来存放启动的入口类(控制类) 二…

使用UART烧录N76E003AT20核心板

目录 模块简介烧录方式利用ISP对N76E003AT20核心板进行烧录ICP烧录BootloaderISP烧录程序&#xff08;UART&#xff09;测试现象 总结 模块简介 N76E003为带有flash的增强型8位8051内核微控制器&#xff08;1T工作模式&#xff09;&#xff0c;指令集与标准的80C51完全兼容并具…

2023年中国超声波治疗仪发展趋势分析:中高端市场国产化率将稳步上升[图]

超声波治疗机是运用超声波治疗疾病的医用设备。主要由电源&#xff0c;高频振荡电路、超声波能治疗头组成。治疗时应正确掌握超声输出强度、治疗时间和选择不同的工作方式。目前超声波技术在医疗方面的独特疗效已得到医学界的普遍认可&#xff0c;且受到了越来越多临床重视和采…

性格迥异的夫妻最后会走到一地鸡毛还是相互成就?「串台:老公不在家」

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 创业舞台的夫妻博弈&#xff0c;台上台下都是戏。 《老公不在家》车厘子来串台啦&#xff01;不叁不肆今日报道&#xff1a; 姝琦和车厘…

【工作记录】springboot应用实现license认证

前言 License授权是一种常见的商业模式&#xff0c;一般用于在客户端部署项目后进行使用人员或功能限制&#xff0c;也常用于软件的试用场景。 主要实现思路就是在服务端生成密钥对及证书&#xff0c;在客户端启动或访问过程中进行验证。 本文实现的是通过IP地址、MAC地址、…

Vue数据绑定

在我们Vue当中有两种数据绑定的方法 1.单向绑定 2.双向绑定 让我为大家介绍一下吧&#xff01; 1、单向绑定(v-bind) 数据只能从data流向页面 举个例子&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"…

vue-组件生命周期+网络请求

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue-组件生命周期网络请求 目录 组件生命周期 1. Vue的生命周期 2. Vue 子组件和父组件执行顺序…

“具有分布式能源资源的多个智能家庭的能源管理的联邦强化学习”文章学习三——基于联邦深度学习的多智能家居能源管理

一、系统描述 我们考虑一个基于FRL的HEMS&#xff0c;它由单个GS和N个LHEMS组成&#xff0c;如图2所示。如图2-C所示&#xff0c;FRL训练过程包括两个步骤&#xff1a;步骤1&#xff09;使用本地数据对LHEMS&#xff08;即本地神经网络的权重ωn&#xff09;进行本地模型的训练…

9步打造个人ip

什么是个人IP&#xff1f; 就是一个人创造出来的属于自己的有个性有价值的&#xff0c;能让他人记住你&#xff0c;信任你&#xff0c;认可你的东西。 如何强化个人IP呢&#xff1f; 需要一些必要的条件如专业性、耐心、勤奋等等要知道&#xff0c;打造IP是一个见效慢的过程&am…

MATLAB中zticks函数用法

目录 语法 说明 示例 指定 z 轴刻度值和标签 指定非均匀 z 轴刻度值 以 2 为增量递增 z 轴刻度值 将 z 轴刻度值设置回默认值 指定特定坐标区的 z 轴刻度值 删除 z 轴刻度线 zticks函数的功能是设置或查询 z 轴刻度值。 语法 zticks(ticks) zt zticks zticks(auto)…

Postman接收列表、数组参数@RequestParam List<String> ids

示例如下: 接口定义如下: GetMapping(value "/queryNewMoviePath")public List<Map<String, Object>> queryNewMoviePath(RequestParam List<String> ids ) {return service.queryNewMoviePath(ids);}postman中测试如下&#xff1a; http://loc…

计算机毕业设计项目选题推荐(免费领源码)java+mysql二手校园交易平台67613

目录 摘要 1 绪论 1.1 研究背景 1.2国内外研究现状 1.3论文结构与章节安排 2 二手校园交易平台系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.5本章小结 …

TensorRT基础知识及应用【学习笔记(十)】

这篇博客为修改过后的转载&#xff0c;因为没有转载链接&#xff0c;所以选了原创 文章目录 一、准备知识1.1 环境配置A. CUDA DriverB. CUDAC. cuDNND. TensorRT 1.2 编程模型 二、构建阶段2.1 创建网络定义2.2 配置参数2.3 生成Engine2.4 保存为模型文件2.5 释放资源 三、运…

C/C+=内存管理

C/C内存管理以及动态内存的申请_c动态内存的申请与释放_Demo Test的博客-CSDN博客 问题是&#xff0c;这个0x0804 8000 到0xC 0000 0000之间&#xff0c;不止3GB&#xff0c;应该有47GB&#xff0c;该怎么解释呢&#xff1f;

Azure的AI使用-(语言检测、图像分析、图像文本识别)

1.语言检测 安装包&#xff1a; # 语言检测 %pip install azure-ai-textanalytics5.2.0 需要用到密钥和资源的终结点&#xff0c;所以去Azure上创建资源&#xff0c;我这个是创建好的了然后点击密钥和终结者去拿到key和终结点 两个密钥选择哪个都行 语言检测代码示例&#…