【JVM】内存模型
文章目录
- 内存模型的基本概念
- 案例
- 程序计数器
- 栈
- `Java`虚拟机栈
- 局部变量表
- 栈帧中局部变量表的实际状态
- 栈帧中存放的数据有哪些
- 操作数栈
- 帧数据
- 本地方法栈
- 堆
- 堆空间是如何进行管理的?
- 方法区
- 静态变量存储
- 直接内存
- 直接内存的作用
内存模型的基本概念
在前面的学习中,我们知道了字节码文件(.class)会通过类加载器加载到JVM虚拟机中,接下来JVM虚拟机就会执行其中的字节码指令.我们把JVM虚拟机被分配的内存叫做运行时数据区域
而内存模型就是指运行时数据区域中被划分的不同区域.
JDK6版本:
字符串常量池存放在方法区中,方法区存放在堆中;
JDK1.7版本:

-
方法区脱离堆,单独占用一部分内存
-
字符串常量池依旧存储在堆中
JDK1.8版本:

-
方法区发生移动,从
JVM虚拟机内存中,移动到本地内存中
Java虚拟机(JVM)的内存模型是Java程序运行时内存管理的基础。它定义了Java程序如何在内存中分配、使用和回收资源。
案例
class Person{int id;String name;public Person(int id,String name){this.id=id;this.name=name;}
}
public class JvmTest {public void func1(int a){int b=10;Person p=new Person(1,"张三");a=11;}public static void main(String[] args) {int a=10;new JvmTest().func1(a);System.out.println(a);}
}

程序计数器
- 控制程序解释执行指令的顺序.在代码执行过程中,程序计数器会记录下一行字节码指令的地址.执行完当前指令之后,虚拟机的执行引擎根据程序计数器执行下一行指令.程序计数器可以控制程序指令的进行,实现分治,跳转或者异常等等逻辑
- 保证在多线程的情况下线程之间的切换.
JVM虚拟机需要通过程序计数器记录CPU切换前解释执行到哪一行指令并继续解释运行
程序计数器会不会发生内存溢出?
内存溢出:程序在使用某一块内存区域时,存放的数据需要占用的内存大小超过了虚拟机能够提供的内存上限
程序计数器不会发生内存溢出的情况.原因:每个程序计数器只会存储一个固定长度的内存地址,也就是字节码指令的内存地址.
栈
Java虚拟机栈
保存在java中实现的方法
采用栈的数据结构来管理方法调用中的基本数据,先进后出,每一个方法的调用使用一个栈帧来保存.
Java虚拟机栈随着线程的创建而创建,随着线程的结束而销毁
在每一个栈帧中,存放的内容有:局部变量表,操作数栈,帧数据

局部变量表
在方法执行过程中存放所有的局部变量,编译成字节码文件时,就可以确定局部变量表的内容

栈帧中局部变量表的实际状态
栈帧中的局部变量表是一个数组,数组中的每一个位置称之为槽,long和double类型占用两个槽,其他类型占用一个槽.

栈帧中存放的数据有哪些
- 实例方法中的序号为
0的位置存放的是this,指的是当前调用方法的实例对象,运行时会在内存中存放实例对象的地址 - 方法参数也会保存在局部变量表中,其顺序与方法中参数定义的顺序一致
局部变量表保存的内容有:
- 实例方法的
this对象- 方法的参数
- 方法体声明的局部变量
为了节省空间,局部变量表中的槽是可以复用的,一旦某个局部变量不再生效,当前槽就可以再次被使用
操作数栈
操作数栈是栈帧中虚拟机执行指令过程中用来存放临时数据的一块区域
- 操作数栈是栈帧中虚拟机在执行指令的过程中用来存放中间数据的一块区域.他是一种栈式的数据结构,如果一条指令将一个值压入操作数栈,则后面的指令可以弹出并使用该值.
比如:在字节码指令执行的过程中,会产生一些临时数据,这些临时数据会先存放到操作数栈中,然后再通过下一条指令放入到局部变量表中
- 在编译期就可以确定操作数栈的最大深度,从而执行时正确的分配内存大小
帧数据
(这个并不是由虚拟机设定标准)
帧数据主要包含动态链接,方法出口,异常表引用
-
动态链接:当前类的字节码指令引用了其他类的属性或者方法时,需要将符号引用(编号)转换成对应的运行时常量池中的内存地址.动态链接就保存了编号到运行时常量池的内存地址的映射关系.

-
方法出口:方法在正确或者异常结束时,当前栈帧会被弹出,同时程序计数器应该指向上一个栈帧中的下一条指令的地址.所以在当前栈帧中,需要存储此方法出口的地址.
-
异常表:存放的是代码中异常的处理信息,包含了异常捕获的生效范围以及异常发生后跳转到的字节码指令位置.
Java虚拟机栈是否会出现栈内存溢出?
Java虚拟机栈如果栈帧过多,占用内存超过栈内存可以分配的最大容量,就会出现栈溢出(虚拟机为每一个线程分配的栈的大小是有限的)Java虚拟机栈内存溢出时会出现StackOverflowError的错误
本地方法栈
保存的是在java中实现的使用native修饰的,实际是由C++编写的本地方法
Java虚拟机栈存储了Java方法调用时的栈帧,而本地方法栈存储的是native本地方法的栈帧.- 在
HotSpot虚拟机中,Java虚拟机栈和本地方法栈实现上使用了同一个栈空间.本地方法栈在栈内存上生成一个栈帧,临时保存方法的参数同时方便出现异常时也把本地方法的栈信息打印出来.

堆
一般Java程序中堆内存是空间最大的一块内存区域.创建出来的对象都存在于堆上
Java 堆是所有线程共享的一块内存,在虚拟机启动时创建,几乎所有的对象实例都存放在这里,是垃圾收集器管理的主要区域。
栈上的局部变量表中,可以存放堆上对象的引用.静态变量也可以存放堆对象的引用,通过静态变量就可以实现对象在线程之间的共享.

堆内存是否会出现溢出?
堆内存大小是有上限的,当对象一直向堆中放入对象达到上限之后,就会抛出OutOfMemory错误
堆空间是如何进行管理的?
堆空间有三个需要关注的值:uesd,total,max
used指的是当前已经使用的堆内存;total是java虚拟机已经分配可用堆内存;max是java虚拟机可以分配的最大堆的内存
随着堆中对象增多,当total可以使用的内存即将不足的时候,虚拟机会继续分配内存给堆,扩展total的大小
- 如果堆内存不足,
java虚拟机就会不断地分配内存,total值会变大.- 是不是当
used=total=max,就会导致内存溢出?
答案:不一定
在实际应用中一般都需要设置total 和 max的值
- 要修改堆的大小,可以使用虚拟机参数
-Xmx(max最大值)和-Xms(初始的total)- 语法:
-Xmx值,-Xms值 - 单位:字节(默认,必须是
1024倍数),K或者k(KB),m或者M(MB),g或者G(GB) - 限制:
Xmx必须大于2MB,Xms必须大于1MB
- 语法:
Java服务端程序开发的时候,建议将-Xmx和-Xms设置为相同的值(total=max),这样在程序启动之后可使用的总内存就是最大内存,而无需向Java虚拟机再次申请,减少了申请并分配内存时间上的开销,同时也不会出现内存过剩之后堆收缩的情况
方法区
方法区是存放每个类基础信息的位置,线程共享,主要包含三部分内容:
- 类的元信息:每个类的基本信息
一般称之为InstanceKlass对象.在类加载阶段完成

- 运行时常量池
- 常量池中存放的是字节码中的常量池内容
- 字节码文件中通过编号查表的方式找到常量,这种常量池称之为静态常量池
- 当常量池加载到内存中之后,可以通过内存地址快速的定位到常量池中的内容,这种常量池称之为运行时常量池.

- 字符串常量池:保存了字符串常量
字符串常量池存储在代码中定义的常量字符串内容.比如:"123",这个123就会被放入字符串常量池

这里我们再来举个例子加深印象:
举例1:
public class StringTest {public static void main(String[] args) {String a="1";String b="2";String c="12";String d=a+b;System.out.println(c==d);}
}
这里的运行结果就代表了我们的d是存放在字符创常量池中还是堆内存中.
运行结果false,原因如下:

举例2:
public class StringTest {public static void main(String[] args) {String a="1";String b="2";String c="12";String d="1"+"2";System.out.println(c==d);}
}
运行结果是:true,为什么?
我们来观察一下此时的字节码指令状态:

所以,此处d存放在常量池中的原因是:这里并没有使用StringBuilder对象来进行字符串的相加,而是直接使用的ldc字节码指令进行的,没有使用对象,所以就不需要存放在堆中
静态变量存储
- 在
JDK7之前的版本中,静态变量是存放在方法区中的,也就是永久代 - 在
JDK7及其之后的版本中,静态变量时存放在堆中的Class对象中,脱离了永久代
直接内存
首先我们要确定的是,直接内存并不属于Java运行时的内存区域.
在JDK1.4中引入了NIO机制,使用了直接内存,主要为了解决以下两个问题:
Java堆中的对象如果不再使用要回收,回收时会影响对象的创建和使用(可能会出现卡顿的现象)IO操作比如读文件,需要先把文件读入直接内存中,再把数据复制到Java堆中.
现在放入直接放入到直接内存中即可,同时在Java堆上维护直接内存的引用,减少了数据复制的开销.写文件也是这种思路.

直接内存的作用
- 提高读写文件的性能
- 避免垃圾回收机制影响对象的创建和使用
- 在`JDK1.78即之后存放方法区
相关文章:
【JVM】内存模型
文章目录 内存模型的基本概念案例 程序计数器栈Java虚拟机栈局部变量表栈帧中局部变量表的实际状态栈帧中存放的数据有哪些 操作数栈帧数据 本地方法栈 堆堆空间是如何进行管理的? 方法区静态变量存储 直接内存直接内存的作用 内存模型的基本概念 在前面的学习中,我们知道了字…...
代码随想录:二叉树的四种遍历
144. 二叉树的前序遍历 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullpt…...
【Linux】从多线程同步到生产者消费者模型:多线程编程实践
目录 1.线程的同步 1.1.为什么需要线程的同步? 2.2.条件变量的接口函数 2.生产消费模型 2.1 什么是生产消费模型 2.2.生产者消费者模型优点 2.3.为何要使用生产者消费者模型 3.基于BlockingQueue的生产者消费者模型 3.1为什么要将if判断变成whileÿ…...
如何在word里面给文字加拼音?
如何在word里面给文字加拼音?在现代社会,阅读已经成为了我们日常生活中不可或缺的一部分。尤其是在学习汉语的过程中,拼音的帮助显得尤为重要。为了帮助大家更好地理解和掌握汉字的发音,许多教师和学生都希望能够在Word文档中为文…...
Detr论文精读
摘要: 作者提到,该方法将物体检测看做直接的集合预测,在传统的目标检测算法中,会先生成候选区域,然后对每个候选区域进行单独的预测(包括物体的分类和预测框的回归),集合预测就是直…...
找寻孤独伤感视频素材的热门资源网站推荐
在抖音上,伤感视频总是能够引起观众的共鸣,很多朋友都在寻找可以下载伤感视频素材的地方。作为一名资深的视频剪辑师,今天我来分享几个提供高清无水印伤感素材的网站,如果你也在苦苦寻找这些素材,不妨看看以下推荐&…...
大模型~合集13
我自己的原文哦~ https://blog.51cto.com/whaosoft/12302606 #TextRCNN、TextCNN、RNN 小小搬运工周末也要学习一下~~虽然和世界没关 但还是地铁上看书吧, 大老勿怪 今天来说一下 文本分类必备经典模型 模型 SOTA!模型资源站收录情况 模型来源论文 RAE ht…...
【Next.js 项目实战系列】04-修改 Issue
原文链接 CSDN 的排版/样式可能有问题,去我的博客查看原文系列吧,觉得有用的话,给我的库点个star,关注一下吧 上一篇【Next.js 项目实战系列】03-查看 Issue 修改 Issue 添加修改 Button 本节代码链接 安装 Radix UI 的 Ra…...
【Linux】并行与并发(含时间片)
简单来说 并发:多个进程轮流使用同一个CPU,在逻辑层面上,一段时间内推进完成了多个进程 并行:机器中有多个CPU可以使用,在物理层面上,做到同一时间会有多个进程同时在运行 举个例子:一群人需要…...
【Flutter】页面布局:弹性布局(Flex)
在 Flutter 开发中,布局是非常重要的部分。布局系统允许开发者控制和管理界面上的组件如何排列和展示。弹性布局(Flex)是其中一个非常强大且常用的布局组件,它能够在水平方向或垂直方向上灵活调整子组件的空间分配比例。Row 和 Co…...
深入解析 Go 语言接口:多接口实现与接口组合的实际应用
文章目录 一、引言二、一个类型实现多个接口1. 定义多个接口2. 类型实现多个接口3. 使用多个接口 三、接口的组合1. 接口嵌套2. 实现复合接口 四、实际开发中的应用场景1. 多态与模块化设计2. 松耦合系统设计3. 测试与依赖注入4. 事件驱动架构中的应用 五、小结 一、引言 在 G…...
Eclipse——Java开发详解
Eclipse 1、配置JDK2、设置编译版本2.1、全局编译版本2.2、项目编译版本2.3、Web项目编译版本 3、设置工作目录4、创建Java项目5、配置Tomcat6、创建Web项目7、配置Maven8、创建Maven项目8.1、普通Maven项目8.2、Maven Web项目 9、创建SpringBoot项目10、设置字体11、设置代码提…...
练手小项目推荐
以下是一些练手项目推荐,我可以给你一些适合学生毕业设计的小项目建议,既可以锻炼技能,也能完成学术要求。以下是一些可行的毕业设计项目建议: 校园导航APP 功能:为校园内的新生和访客提供导航,标记教室、…...
一图秒懂色彩空间和色彩模型
色彩空间和色彩模型 想必学过图像处理或者摄影的小伙伴都知道这两个词,看了一些博客,发现很少有人把这两个概念说清楚的,大多数都是混在一起,色彩模型和色彩空间的概念混为一谈,很让人疑惑。 这里我们用一张图来解…...
控制Stable Diffusion生成质量的多种方法
在Stable Diffusion绘图中,控制AI生成图像的质量可以通过多种方法来实现。以下是几种常见的方法: 1. 从底模控制(Checkpoint) 使用不同的模型检查点(Checkpoints)可以显著影响生成图像的质量和细节。选择一…...
递归算法笔记
根据b站视频整理的 **视频地址:**https://www.bilibili.com/video/BV1S24y1p7iH/?spm_id_from333.788.videopod.sections&vd_source6335ddc7b30e1f4510569db5f2506f20 最常见的一个递归例子: 斐波那契数列:1,2,3…...
Android——发送彩信
跳转到相册选择图片 btn_jump.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {// 跳转到系统相册选择图片并返回Intent intent new Intent(Intent.ACTION_GET_CONTENT);// 设置图片类型为图片类型intent.setType("image/*&quo…...
对比迁移项目的改动
文章目录 对比迁移项目的改动场景背景解决方案 对比迁移项目的改动 场景背景 同源定制化项目,同一套代码扩展出来的项目(从领导口中得知) A项目的有三维地图展示,项目B跑起来却加载不出来,但是本地运行A项目代码&…...
数据结构-复杂度
复杂度 1.数据结构1.1算法 2.算法效率2.1复杂度的概念 3.时间复杂度3.1大O渐进表示法3.2时间复杂度计算示例3.2.1 示例13.2.2 示例23.2.3 示例33.2.4 示例43.2.5 示例5:3.2.6 示例63.2.7 示例7 4.空间复杂度4.1.1 示例14.1.2 示例2 5.常见复杂度对比6.复杂度算法题6…...
无人机之放电速率篇
无人机的放电速率是指电池在一定时间内放出其储存电能的能力,这一参数对无人机的飞行时间、性能以及安全性都有重要影响。 一、放电速率的表示方法 放电速率通常用C数来表示。C数越大,表示放电速率越快。例如,一个2C的电池可以在1/2小时内放…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

