【JVM】Java程序运行时数据区

article/2025/7/15 15:17:24

运行时数据区

运行时数据区是Java程序执行过程中管理的内存区域

在这里插入图片描述

Java 运行时数据区组成(JVM 内存结构)

Java 虚拟机(JVM)的运行时数据区由以下核心部分组成:

线程私有:程序计数器、Java虚拟机栈、本地方法栈。

线程共享:方法区、堆。

在这里插入图片描述

一、程序计数器

程序计数器存储当前执行的字节码指令地址。

线程私有:每个线程都有独立的程序计数器。

多线程场景下程序计数器的工作流程:

Thread1 CPU Thread2 执行指令 [PC=15] 时间片用完 保存PC值(15) 恢复执行 [PC=22] 执行指令... 时间片用完 保存PC值(25) 恢复执行 [PC=15] 继续执行下条指令 Thread1 CPU Thread2

常见问题解答

Q:为什么程序计数器不会内存溢出?
A:其存储的是单个指令地址(指针),非用户数据。指针长度固定(32位系统4字节/64位8字节),且线程结束时自动释放。

Q:PC 如何影响程序流程控制?
A:分支指令直接修改 PC 值实现跳转:

0: iload_1
1: ifeq 12      // 如果值为0,PC跳转到12
4: iinc 1, -1   // 否则继续执行
...
12: return      // 跳转目标

Q:调试器如何实现断点功能?
A:通过修改 PC 值实现:

  1. 在目标指令处插入特殊断点指令
  2. 当 PC 指向断点时暂停执行
  3. 显示当前堆栈和变量状态

二、Java虚拟机栈

Java虚拟机栈描述的是Java方法执行过程中的线程内存模型,主要作用是管理Java方法的调用过程。在当前线程中每个方法被调用的时候,JVM会同步创建一个栈帧呀入到虚拟机栈。栈帧中存储着局部变量表、操作数栈、动态链接、方法返回地址等。

栈帧组成

1. 局部变量表
  • 存储内容

    • this(实例对象的地址)

    • 方法参数

    • 局部变量

    • 基本类型数据(int, boolean 等)

    • 对象引用(reference)

      在这里插入图片描述

  • 容量单位变量槽(Slot)

    • 32位类型占1个Slot(int, float, reference

    • 64位类型占2个Slot(long, double

      索引类型名称大小示例值
      0referencethis1槽0x00a3b1
      1inta1槽10
      2doubleb2槽20.5
      4referencec1槽0x00c4d2
      5longd2槽100
  • 内存复用:Slot在作用域结束后可被复用

public void demo(int param) {int a = 10;          // Slot 0: this | Slot 1: param | Slot 2: adouble b = 20.0;     // Slot 3-4: b (占2个Slot)String s = "hello";  // Slot 5: s
}
2. 操作数栈
  • 作用:执行字节码指令的工作区

  • 深度:编译期确定(写入方法表的 max_stack 属性)

  • 示例代码及执行过程

    以下面的 Java 代码为例,分析操作数栈在方法执行过程中的具体工作情况。

    public class OperandStackExample {public static int add(int a, int b) {int c = a + b;return c;}public static void main(String[] args) {int result = add(3, 5);System.out.println(result);}
    }
    
    编译后的字节码分析

    add 方法编译后的部分字节码如下:

    public static int add(int, int);Code:0: iload_0         // 将局部变量表中第 0 个位置的 int 型变量(参数 a)压入操作数栈1: iload_1         // 将局部变量表中第 1 个位置的 int 型变量(参数 b)压入操作数栈2: iadd            // 从操作数栈中弹出两个 int 型操作数,相加后将结果压入操作数栈3: istore_2        // 将操作数栈顶的 int 型结果弹出,存入局部变量表中第 2 个位置(变量 c)4: iload_2         // 将局部变量表中第 2 个位置的 int 型变量(变量 c)压入操作数栈5: ireturn         // 将操作数栈顶的 int 型结果返回
    
    操作数栈状态变化
    1. 执行 iload_0 指令后:将参数 a(值为 3)压入操作数栈,此时操作数栈栈顶元素为 3。
    2. 执行 iload_1 指令后:将参数 b(值为 5)压入操作数栈,此时操作数栈从栈顶到栈底元素依次为 5、3。
    3. 执行 iadd 指令后:从操作数栈中弹出 5 和 3,计算 3 + 5 = 8,将结果 8 压入操作数栈,此时操作数栈栈顶元素为 8。
    4. 执行 istore_2 指令后:将操作数栈顶的 8 弹出,存入局部变量表中变量 c 的位置,此时操作数栈为空。
    5. 执行 iload_2 指令后:将局部变量表中变量 c 的值 8 压入操作数栈,此时操作数栈栈顶元素为 8。
    6. 执行 ireturn 指令后:将操作数栈顶的 8 返回,方法执行结束。
3. 动态链接
  • 存储内容:指向方法区运行时常量池的引用
  • 核心作用:将符号引用解析为直接引用
    • 类方法调用:确定目标方法的入口地址
    • 字段访问:定位字段在内存中的偏移量
4. 方法返回地址
  • 两种返回方式
    • 正常返回:PC计数器值作为返回地址
    • 异常退出:异常处理器表记录的地址
  • 关键动作
    • 恢复上层方法的局部变量表
    • 将操作数栈结果压回调用者栈帧
    • 调整PC计数器

三、本地方法栈

本地方法栈是 JVM 为执行本地方法(Native Method)提供的内存区域。本地方法是使用非 Java 语言(如 C、C++)实现的方法,主要作用是管理本地方法的调用过程。

栈帧结构

本地方法栈的栈帧结构和 Java 虚拟机栈的栈帧类似,通常包含以下部分:

局部变量表:用于存储本地方法执行过程中的局部变量,包括基本数据类型和对象引用。
操作数栈:在本地方法执行计算时,用于存储操作数和中间结果。
动态链接:将符号引用转换为直接引用,以便在运行时能够正确调用方法。
方法返回地址:记录方法执行完毕后返回的位置。

以上都是线程不共享,每个线程私有的内存区域,与每个线程当前执行位置与内存模型息息相关,都在线程创建时创建,在线程销毁时销毁。

四、方法区

方法区存放着已经被虚拟机加载的类型信息、常量、静态变量等数据。

储存内容

  • 类型信息:

    • 类的全限定名(如 java.lang.String
    • 类的直接父类的全限定名(对于 Object,没有父类)
    • 类的修饰符(public, abstract, final 等)
    • 实现的接口列表
    • 字段信息(字段名称、类型、修饰符)
    • 方法信息(方法名称、返回类型、参数类型/数量、修饰符、字节码、操作数栈和局部变量表大小)
  • 运行时常量池:

    • 是字节码文件中常量池的运行时表现形式,被每个类或接口所独有。
    • 包含:
      • 编译期已知的字面量:文本字符串、final 常量值。
      • 符号引用:类和接口的完全限定名、字段的名称和描述符、方法的名称和描述符。这些符号引用在类加载的解析阶段会被转化为直接引用(如内存地址)。

    JDK 7 之后,字符串常量池从方法区移到了堆中,但其他类型的常量(如整数常量、浮点常量等)依然存于运行时常量池,位于元空间。

  • 静态变量:

    • 静态变量存储在方法区,可供所有的实例访问。

实现演变

  • 永久代(JDK7及以前):方法区使用永久代实现,永久代使用堆中的一部分内存,有固定大小限制,容易发生内存溢出。
  • 元空间(JDK8以后):移除永久代,使用元空间实现方法区,元空间使用系统直接内存,不再受堆内存的限制。

五、堆

在JVM中,堆的作用是存放所有的对象实例。堆被所有的线程共享。

存储内容

1.对象实例

  • 所有new创建的对象。
  • 数组对象:
    • int[], double[] 等基本类型数组(数组对象本身及其元素值都在堆中连续空间中)。
    • String[], Object[] 等引用类型数组(数组对象本身在堆中,其元素是指向堆中其他对象的引用)。

易混淆点

  1. 字符串对象与字符串常量池
    • 字符串对象本身(如 new String("abc") 或运行时拼接生成的 String存储在堆中
    • 字符串常量池自 JDK 7 起移至堆中,它存储的是:
      • 字符串字面量(如 "abc")的引用(指向堆中的 String 对象)。
      • String.intern() 方法返回的字符串的引用。
    • 总结:字符串对象在堆,常量池(StringTable)也在堆(存储引用),但常量池本身是一个哈希表结构。
  2. 静态变量引用的对象
    • 静态变量(static 修饰)的引用本身存储在方法区(JDK 7+ 的元空间)。
    • 静态变量指向的对象实例(如 static Object obj = new Object(); 中的 new Object()存储在堆中
  3. **类信息:
    • 类的元数据(如类名、方法字节码、字段结构等)存储在方法区(元空间)不在堆中
    • 类的 Class 对象(如 String.class)是一个特殊的对象实例,存储在堆中
  4. 基本类型局部变量 vs. 成员变量
    • 成员变量(在对象内部):基本类型(如 int, double)的值直接存在堆内对象内存中。
    • 局部变量(在方法内部):基本类型(如 int i = 10;)的值存储在 Java 栈的栈帧的局部变量表 中,不在堆中

http://www.hkcw.cn/article/vaBNWaiuTI.shtml

相关文章

力扣面试150题--二叉树的层平均值

Day 54 题目描述 思路 初次做法(笨):使用两个队列,一个队列存放树的节点,一个队列存放对应节点的高度,使用x存放上一个节点,highb存放上一个节点的高度,sum存放当前层的节点值之和…

机器学习与深度学习01--线性回归

目录 1.什么是线性回归2.如何用数学方式描述简单线性回归模型3.什么是最小二乘法,他有什么作用 1.什么是线性回归 线性回归是⼀种⼴泛⽤于统计学和机器学习中的回归分析⽅法,⽤于建⽴⾃变量(特征)与因变量(⽬标&#…

004时装购物系统技术解析:构建智能时尚消费平台

时装购物系统技术解析:构建智能时尚消费平台 在电商行业蓬勃发展的当下,时装购物系统凭借其便捷性与多样性,成为消费者选购时尚单品的重要渠道。该系统通过商品信息、订单管理等核心模块,结合前台展示与后台录入功能,…

无线通信模块简介

QuecPython 是运行在无线通信模块上的开发框架。对于首次接触物联网开发的用户而言,无线通信模块可能是一个相对陌生的概念。本文主要针对无线通信和蜂窝网络本身,以及模块的概念、特性和开发方式进行简要的介绍。 无线通信和蜂窝网络 物联网对无线通信…

从认识AI开始-----解密门控循环单元(GRU):对LSTM的再优化

前言 在此之前,我已经详细介绍了RNN和LSTM,RNN虽然在处理序列数据中发挥了重要的作用,但它在实际使用中存在长期依赖问题,处理不了长序列,因为RNN对信息的保存只依赖一个隐藏状态,当序列过长,隐…

历年西北工业大学计算机保研上机真题

2025西北工业大学计算机保研上机真题 2024西北工业大学计算机保研上机真题 2023西北工业大学计算机保研上机真题 在线测评链接:https://pgcode.cn/school 计算整数乘积 题目描述 给定 n n n 组数,每组两个整数,输出这两个整数的乘积。 …

ansible-playbook 进阶 接上一章内容

1.异常中断 做法1:强制正常 编写 nginx 的 playbook 文件 01-zuofa .yml - hosts : web remote_user : root tasks : - name : create new user user : name nginx-test system yes uid 82 shell / sbin / nologin - name : test new user shell : gete…

基于cornerstone3D的dicom影像浏览器 第二十七章 设置vr相机,复位视图

文章目录 前言一、VR视图设置相机位置1. 相机位置参数2. 修改mprvr.js3. 调用流程1) 修改Toolbar3D.vue2) 修改View3d.vue3) 修改DisplayerArea3D.vue 二、所有视图复位1.复位流程说明2. 调用流程1) Toolbar3D中添加"复位"按钮,发送reset事件2) View3d.vu…

以色列防长:哈马斯要么接受美方提案 要么面临毁灭

当地时间5月30日,以色列国防部长卡茨通过其个人社交媒体账号发表声明称,在以军强大的军事压力之下,巴勒斯坦伊斯兰抵抗运动(哈马斯)将被迫接受选择:接受美方提出加沙停火提案,或者被以色列消灭。△以色列国防部长卡茨(资料图)卡茨在声明中表示,当前以军正全力在加沙地…

古巴外交部召见美国临时代办 抗议其无礼行为

△古巴哈瓦那(资料图)当时间5月30日,古巴外交部召见了美国驻古巴临时代办迈克哈默(Mike Hammer)并表示,迈克哈默自2024年11月抵达古巴以来,对古巴表现出的不友好行为,既不符合他外交官的身份,也表现了对古巴人民的不尊重。古巴外交部美国双边事务总司主任加西亚向迈克…

Java处理动态的属性:字段不固定、需要动态扩展的 JSON 数据结构

引言 应用场景: 签名测试接口、表单配置项、参数列表、插件信息等。技术实现:JSONObject 接收、使用json格式的字符串,或者@JsonAnySetter/@JsonAnyGetter注解方法来处理动态的属性。I JSONObject 接收和返回 例子:表单配置 接口对应的表单配置信息 JSONObject 接收和返回…

leetcode1201. 丑数 III -medium

1 题目:1201. 丑数 III. 官方标定难度:中 丑数是可以被 a 或 b 或 c 整除的 正整数 。 给你四个整数:n 、a 、b 、c ,请你设计一个算法来找出第 n 个丑数。 示例 1: 输入:n 3, a 2, b 3, c 5 输出…

【Oracle】DML语言

个人主页:Guiat 归属专栏:Oracle 文章目录 1. DML概述1.1 什么是DML?1.2 DML的核心功能 2. INSERT语句详解2.1 基础插入操作2.2 子查询插入2.3 多表插入2.4 批量插入优化 3. UPDATE语句详解3.1 基础更新操作3.2 关联更新3.3 批量更新优化 4. …

安装启动Mosquitto以及问题error: cjson/cJSON.h: No such file or directory解决

安装Mosquitto 在官方下载地址:https://mosquitto.org/files/source/ 选择版本下载 安装环境是linux centos7,上传 mosquitto-2.0.18.tar.gz 文件到 /mqtt 文件夹下 tar -xvf mosquitto-2.0.18.tar.gz #解压 cd mosquitto-2.0.18/ #切换到解压目录下…

附件上传唯一性校验

1. Overridepublic String uploadFile(MultipartFile file, String id, String funNo, String ctType) {//TODO 附件重复判断// 计算文件哈希值// 将MultipartFile转换为临时File对象String fileHash "";try {File tempFile convertMultipartFileToFile(file);// …

正点原子AU15开发板!板载40G QSFP、PCIe3.0x8和FMC LPC等接口,性能强悍!

正点原子AU15开发板!板载40G QSFP、PCIe3.0x8和FMC LPC等接口,性能强悍! 正点原子AU15开发板搭载Xilinx Artix UltraScale 系列FPGA,核心板主控芯片的型号是XCAU15P-FFVB676-2I。开发板由核心板+底板组成,外…

Attention-> flashAttention材料参考

1、 一文看懂 Attention(本质原理3大优点5大类型)_attention结构-CSDN博客2​​​​​​​2https://blog.csdn.net/haima1998/article/details/107845549 2、 一文看懂 NLP 里的模型框架 Encoder-Decoder 和 Seq2Seq (easyai.tech) 3、 详解深度学习…

MySQL高可用集群

https://dev.mysql.com/doc/mysql-shell/8.4/en/mysql-innodb-cluster.html 1 什么是MySQL高可用集群 MySQL高可用集群:MySQL InnoDB ClusterInnoDB Cluster是MySQL官方实现高可用读写分离的架构方案,包含以下组件 MySQL Group Replication:简…

山洪灾害声光电监测预警解决方案

一、方案背景 我国是一个多山的国家,山丘区面积约占国土面积的三分之二。每年汛期,受暴雨等因素影响,极易引发山洪和泥石流。山洪、泥石流地质灾害具有突发性、流速快、流量大、物质容量大和破坏力强等特点,一旦发生,将…

2025年最新工程项目管理系统应该具备哪些模块?

随着数字化转型浪潮席卷工程行业,工程项目管理系统的作用愈发凸显。2025年,工程项目管理系统的核心目标不仅是提升项目效率,更在于通过智能化、集成化技术实现全生命周期的精细化管理。基于行业趋势和企业实际需求,结合金众诚工程…