【JVM】运行时数据区域
文章目录
- 说明
- 程序计数器
- 虚拟机栈
- 本地方法栈
- Java堆
- 方法区
- 运行时常量池
- 直接内存
说明
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。如下图,这篇文章简单介绍下各个区域的作用
程序计数器
程序计数器(Program Counter,简称PC)是Java虚拟机(JVM)中的一块内存区域,它是一种较小的、无法被线程切换所影响的内存空间。每个线程都有自己独立的程序计数器,用于存储当前线程执行的字节码指令的地址。
程序计数器在JVM中有以下几个主要作用:
- 线程控制:程序计数器指示了每个线程将要执行的指令地址。在线程切换时,JVM能够恢复到正确的执行点。
- 字节码解释器:在Java中,代码被编译成字节码(bytecode)。程序计数器用于跟踪当前执行的字节码指令,以便字节码解释器能够逐条执行指令。
- 异常处理:当Java程序抛出异常时,JVM会根据异常处理表来确定异常处理代码的位置。程序计数器在这里发挥了关键作用,帮助JVM准确位处理代码的位置。
- 线程私有:每个线程都有自己独立的程序计数器。这使得线程能够独立执行,不受其他线程影响。
简单来说程序计数器就是下一条指令要执行的地址,每个线程都会具有,线程私有。
虚拟机栈
虚拟机栈(Virtual Machine Stack)是Java虚拟机(JVM)为每个线程私有创建的一块内存区域,用于存储方法执行过程中的局部变量、操作数栈、动态链接和方法出口等信息。每个方法在执行时都会创建一个栈帧(Stack Frame)并入栈,方法执行完毕后栈帧出栈。栈帧包含了方法的局部变量、操作数栈、返回地址等信息。
虚拟机栈具有以下几个主要特点:
- 线程私有:每个线程都有自己独立的虚拟机栈,这保证了多线程环境下方法的执行状态不会相互干扰。
- 方法调用:虚拟机栈用于保存方法调用的状态。每次方法调用时,会在虚拟机栈上创建一个栈帧,栈帧包含了方法的局部变量、操作数栈等信息。
- 局部变量和操作数栈:栈帧内部包含局部变量表和操作数栈。局部变量表用于存储方法中的局部变量,而操作数栈用于执行操作码(字节码指令)时的临时存储。
- 异常处理:虚拟机栈也参与异常处理机制。当方法内部发生异常而未被捕获时,虚拟机会查找虚拟机栈来定位异常发生的位置,以便于异常处理。
需要注意的是,虚拟机栈的大小是可以配置的,并且栈空间有可能会发生栈溢出(Stack Overflow)异常。栈溢出通常是由于递归调用深度过大或者局部变量表和操作数栈占用的空间过大导致的。
简单来说每个方法就对应一个栈帧,方法调用和执行就代表了栈帧的出栈和入栈操作,栈帧里面就存放了方法的一些必要信息。
本地方法栈
本地方法栈(Native Method Stack)与虚拟机栈类似,是Java虚拟机为执行本地方法(Native Method)而准备的一块内存区域。本地方法指的是用非Java语言(通常是C、C++等)编写的方法,这些方法可以通过Java的本地接口(JNI,Java Native Interface)在Java程序中调用。
本地方法栈是为了支持Java程序与非Java本地方法之间的交互而存在的内存区域,类似于虚拟机栈,但用于本地方法的调用和执行。
Java堆
当我们在编写Java程序时,所有的对象实例(比如类的实例、数组等)都需要在内存中存储。Java堆就是用来存储这些对象的地方。它是一个非常大的内存区域,被所有线程共享。
关键点如下:
-
对象存储:每次使用
new
关键字创建一个对象时,这个对象都会被分配到Java堆中。无论是我们自己定义的类,还是Java内置的类,都会在堆上分配内存。 -
垃圾回收:Java堆是被垃圾回收器管理的。当一个对象不再被程序引用,也就是没有变量指向它时,垃圾回收器会回收这个对象所占用的内存,以便为将来的对象分配空间。
-
分代结构:Java堆通常被划分为不同的“代”,比如新生代和老年代。新创建的对象会被分配到新生代,而存活时间较长的对象会被移到老年代。这种分代结构有助于提高垃圾回收的效率。
-
内存设置:我们可以通过命令行参数来设置Java堆的初始大小和最大大小。这可以帮助我们优化程序的内存使用。
-
内存溢出:如果我们的程序创建了过多的对象,超过了堆的可用空间,就会引发内存溢出错误,导致程序崩溃。
总之,Java堆是用来存储Java程序中的对象的内存区域,垃圾回收器会在这里管理对象的分配和释放,从而保持程序的正常运行。
方法区
方法区(Method Area)是Java虚拟机中的一块内存区域,用于存储类的元数据信息、静态变量、常量池、方法代码等。它是所有线程共享的,与堆一样,也是Java虚拟机的一部分。
以下是关于方法区的一些要点:
-
元数据信息:方法区主要用于存储类的元数据信息,包括类的名称、访问修饰符、字段信息、方法信息等。这些信息在运行时被Java虚拟机使用,例如在类加载、字节码解析和方法调用等时候。
-
静态变量:静态变量,也叫类变量,被存储在方法区中。这些变量在类加载的过程中被创建并分配内存,它们在整个类的生命周期内保持不变。
-
常量池:常量池是一种存储在方法区中的数据结构,用于存放编译时生成的各种字面量和符号引用。它包括字符串常量、类和接口的全限定名、字段和方法的名称和描述符等信息。
-
方法代码:方法区也存储类的方法代码。这些代码在类被调用时被执行。方法区中存储的方法字节码被解释器或者即时编译器(如HotSpot的C2编译器)执行。
-
运行时常量池:在Java 7 及之前的版本,常量池也包括一部分运行时生成的常量。但从Java 8 开始,运行时常量池已经被移到堆中的一部分,称为运行时常量池。
-
内存溢出:方法区内存溢出错误通常被称为“永久代溢出”,这是因为在Java 7 及之前的版本中,方法区被实现为持久代。随着类加载和卸载的不断进行,方法区的空间也会被耗尽,导致程序崩溃。
需要注意的是,从Java 8 开始,方法区被元空间(Metaspace)所取代。元空间使用的是本地内存而非虚拟机内存,因此它更加灵活,避免了持久代溢出等问题。
总之,方法区是存储类的元数据、静态变量、常量池和方法代码等信息的内存区域,是Java虚拟机重要的组成部分之一。
运行时常量池
当Java类文件被加载到内存中时,会创建一个运行时常量池(Runtime Constant Pool),它是类中常量的一种运行时表示。运行时常量池包含了从类文件的编译时常量池中提取出来的一部分内容,以及在运行时生成的常量。
编译时常量池是位于类文件中的,它包含了类中的各种常量,如字符串、数字、类名、方法名等。而运行时常量池是在类加载时被构建的,用于在程序运行期间支持常量的引用和操作。
运行时常量池不仅包含编译时常量池中的内容,还可能包括一些在运行时生成的常量。例如,字符串拼接的结果、动态方法调用等都可以在运行时常量池中得到体现。
需要注意的是,从Java 8 开始,常量池被移到元空间(Metaspace)中,取代了之前的永久代。元空间具有更大的灵活性,不再受到固定大小的限制。在这种情况下,运行时常量池仍然存在,但它与常量池的管理方式有所不同。
总之,运行时常量池是在类加载后构建的一种数据结构,包含了编译时常量池中的部分内容以及在运行时生成的常量,它为Java程序提供了常量引用和操作的支持。
直接内存
当我们在Java程序中使用内存时,通常会涉及到Java堆内存、栈内存等。而直接内存是一种与传统内存管理方式不同的内存分配方式,主要用于提高I/O操作的性能和效率。直接内存是一种用于提高I/O操作性能的内存分配方式,在Java NIO库中得到广泛应用。虽然它可以提供一些性能优势,但需要开发者自行管理分配和释放,以避免潜在的风险。
传统的Java内存管理方式中,Java堆内存的分配和释放都由JVM的垃圾回收机制进行管理。但是在一些特定场景下,特别是涉及到I/O操作的时候,传统的内存管理方式可能会导致性能问题。这时,直接内存可以作为一个媒介,充当了Java程序和操作系统之间的桥梁,以提高性能和效率。
传统的Java堆内存分配方式涉及以下步骤:
- 应用程序到Java堆内存的拷贝:当数据从应用程序传递到Java堆内存时,需要进行数据拷贝。
- Java堆内存到操作系统的拷贝:当执行I/O操作时,数据需要从Java堆内存复制到操作系统的内核缓冲区。
- 操作系统到Java堆内存的拷贝:I/O操作完成后,数据又需要从操作系统的内核缓冲区复制回Java堆内存。
而使用直接内存的情况下:
- 应用程序到直接内存的拷贝:当数据从应用程序传递到直接内存时,不需要进行数据拷贝,数据直接存储在直接内存中。
- 直接内存到操作系统的拷贝:当执行I/O操作时,数据可以直接从直接内存传递给操作系统的内核缓冲区,避免了数据复制。
- 操作系统到直接内存的拷贝:I/O操作完成后,数据可以直接从操作系统的内核缓冲区传递回直接内存,同样避免了数据复制。
当执行I/O操作时,数据可以直接从直接内存传递给操作系统的内核缓冲区,避免了数据复制。
3. 操作系统到直接内存的拷贝:I/O操作完成后,数据可以直接从操作系统的内核缓冲区传递回直接内存,同样避免了数据复制。
总之,使用直接内存可以减少数据在内存之间的复制,从而提高I/O操作的性能。这种方式特别适用于需要频繁进行大量I/O操作的场景,例如文件读写、网络传输等。然而,需要注意的是,直接内存的管理需要开发者自行负责,如果管理不当,可能会导致内存泄漏和其他问题。
相关文章:

【JVM】运行时数据区域
文章目录 说明程序计数器虚拟机栈本地方法栈Java堆方法区运行时常量池直接内存 说明 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直…...

uniapp踩坑合集
1、onPullDownRefresh下拉刷新不生效 pages.json对应的style中enablePullDownRefresh设置为true,开启下拉刷新 {"path" : "pages/list/list","style" :{"navigationBarTitleText": "页面标题名称","enable…...

再JAVA中如何使用qsort对类进行排序?
目录 结论: 解析: 结论: import java.util.Arrays;class Person implements Comparable<Person>{public String name;public int age;public Person(String name, int age) {this.name name;this.age age;}Overridepublic Stri…...

docker安装clickhouse
安装 docker安装 创建clickhouse目录 mkdir -P /data/clickhouse/datamkdir -P /data/clickhouse/confmkdir -P /data/clickhouse/log 拉取镜像 这里直接拉取最新镜像, 如果需要某个特定版本, 则再拉取的时候指定版本号即可. docker pull clickhouse/clickhouse-server 启动临…...

解决`idea`中`database`工具查询起别名乱码问题
文章目录 解决idea中database工具查询起别名乱码问题场景复现如何解决方式一 设置编码方式二:修改字体 原因说明 解决idea中database工具查询起别名乱码问题 场景复现 使用Idea做查询的并且起别名出现了中文乱码 如何解决 方式一 设置编码 settings->输入框输…...

UE4/5Niagara粒子特效之Niagara_Particles官方案例:1.5->2.3
目录 之前的文章: 1.5 Blend Attributes by Value 发射器更新 粒子生成 粒子更新 2.1 Static Beams 编辑 发射器更新: 粒子生成 粒子更新 2.2 Dynamic Beams 没有开始模拟前的效果是: 开始模拟后的效果是: 发射器更新 …...

Docker 容器数据卷
Docker挂载主机目录访问如果出现cannot open directory .: Permission denied 解决办法:在挂载目录后多加一个--privilegedtrue参数即可 如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行…...

STM32--MPU6050与I2C外设
文章目录 前言MPU6050参数电路MPU6050框图 IIC外设框图 IIC的基本结构软件IIC实现MPU6050硬件IIC实现MPU6050 前言 在51单片机专栏中,用过I2C通信来进行实现AT24C02的数据存储; 里面介绍的是利用程序的编程来实现I2C的时序,进而实现AT24C02与…...

项目管理实战笔记1:项目管理常识
序 看了下极客时间的《项目管理实战》,觉得跟之前学习PMP的标准资料还是有所侧重。重新整理下,相比书上繁杂的知识,这个更通俗易懂。 1 角色转换:三大误区 误区1:事必躬亲 自己做事情是可控的,做项目依赖…...

时序分解 | MATLAB实现基于SVMD逐次变分模态分解的信号分解分量可视化
时序分解 | MATLAB实现基于SVMD逐次变分模态分解的信号分解分量可视化 目录 时序分解 | MATLAB实现基于SVMD逐次变分模态分解的信号分解分量可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 SVMD分解算法,分解结果可视化,MATLAB程序ÿ…...

阿里云访问端口被限制解决方法记录
阿里云服务器,80端口可以访问,但是加入了安全组端口8080 通过公网访问改端口策略,发现不能被访问 问题出在防火墙,需要重置一下 解决方法: 在运行的服务器上执行如下命令: # iptables -A INPUT -j ACCEP…...

antd5源码调试环境启动(MacOS)
将源码下载至本地 这里antd5 版本是5.8.3 $ git clone gitgithub.com:ant-design/ant-design.git $ cd ant-design $ npm install $ npm start前提:安装python3、node版本18.14.0(这是本人当前下载的版本) python3安装教程可参考:https://…...
单片机使用基于时间片轮询系统的-状态机-[1]
目的:【1】用C实现一个超轻量化任务管理系统 【2】具有任务suspend, resume, runonce ,auto loop ,task_delay功能 【3】易于移植,不涉及硬件底层。 示例例码: 利用switch case结构实现了单一层的 task_delay功能。弊端就是switch..case不…...

前端开发怎么解决性能优化的问题? - 易智编译EaseEditing
前端性能优化是确保网站或应用在加载速度、响应性和用户体验等方面达到最佳状态的关键任务。以下是一些解决前端性能优化问题的方法: 压缩和合并代码: 压缩和合并CSS、JavaScript和HTML文件可以减少文件大小,加快加载速度。使用压缩工具&am…...
共享球拍小程序:打破拥有束缚,尽享运动乐趣
市场前景: 随着健身和运动的流行趋势,越来越多的人加入了各种体育项目。然而,拥有球拍作为体育装备的成本较高,对于想要尝试不同运动的人来说,这可能是个阻碍。共享球拍小程序迎合了这一需求,提供了一个经济…...

uniapp 微信小程序 绘制海报,长按图片分享,保存海报
uView UI 2.0 dcloud 插件市场地址 弹窗海报源码 <template><!-- 推荐商品弹窗 --><u-popup :show"haibaoShow" mode"center" round26rpx z-index10076 bgColortransparent safeAreaInsetTop close"goodsclose"><image …...

爬虫异常捕获与处理方法详解
Hey!作为一名专业的爬虫代理供应商,我今天要和大家分享一些关于爬虫异常捕获与处理的方法。在进行爬虫操作时,我们经常会遇到各种异常情况,例如网络连接错误、请求超时、数据解析错误等等。这些异常情况可能会导致程序崩溃或数据丢…...
制作网络课堂学习平台(标签嵌套,后代选择器)
网络课堂学习平台 课程 1 这是课程 1 的描述。 模块 1 这是模块 1 的描述。 查看详情 模块 2 这是模块 2 的描述。 查看详情 课程 2 这是课程 2 的描述。 模块 1 这是块 2 的描述。 查看详情...

基于医疗领域数据微调LLaMA——ChatDoctor模型
文章目录 ChatDoctor简介微调实战下载仓库并进入目录创建conda环境并配置环境(安装相关依赖)下载模型文件微调数据微调过程全量微调基于LoRA的微调基于微调后的模型推理 ChatDoctor简介 CHatDoctor论文: ChatDoctor: A Medical Chat Model F…...

UDP TCP 报文内容
1.UDP 2.TCP 源/目的端口号:表示数据是从哪个进程来,到哪个进程去; 32位序号/32位确认号:后面详细讲;4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是15*460 6位标志位: o URG:紧急指针是否有效 ——urgent 紧急的 o ACK:确认号是否有…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...

AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...

Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...