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

news2025/6/2 14:36:53

运行时数据区

运行时数据区是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: a
    double 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.coloradmin.cn/o/2392675.html

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

相关文章

计算机视觉入门:OpenCV与YOLO目标检测

计算机视觉入门:OpenCV与YOLO目标检测 系统化学习人工智能网站(收藏):https://www.captainbed.cn/flu 文章目录 计算机视觉入门:OpenCV与YOLO目标检测摘要引言技术原理对比1. OpenCV:传统图像处理与机器学…

【Prometheus+Grafana实战:搭建监控系统(含告警配置)】

什么是Prometheus和Grafana? Prometheus:一款开源的监控告警工具,擅长时序数据存储和多维度查询(通过PromQL),采用Pull模型主动抓取目标指标。Grafana:数据可视化平台,支持多种数据…

一文速通Python并行计算:11 Python多进程编程-进程之间的数据安全传输-基于队列和管道

一文速通 Python 并行计算:11 Python 多进程编程-进程之间的数据安全传输-基于队列和管道 摘要: Python 多进程中,Queue 和 Pipe 提供进程间安全通信。Queue 依赖锁和缓冲区,保障数据原子性和有序性;Pipe 实现点对点单…

LangChain-Tool和Agent结合智谱AI大模型应用实例2

1.Tool(工具) 定义与功能 单一功能模块:Tool是完成特定任务的独立工具,每个工具专注于一项具体的操作,例如:搜索、计算、API调用等 无决策能力:工具本身不决定何时被调用,仅在被触发时执行预设操作 输入输出明确:每个工具需明确定义输入、输出参数及格式 2.Agent(…

centos7.6阿里云镜像各个版本介绍

(水一期) Index of /centos-vault/centos/7.6.1810/isos/x86_64/ File NameFile SizeDateParent directory/--0_README.txt2.4 KB2018-12-01 21:21CentOS-7-x86_64-DVD-1810.iso4.3 GB2018-11-26 07:55CentOS-7-x86_64-DVD-1810.torrent86.0 KB2018-12-…

InnoDB引擎逻辑存储结构及架构

简化理解版 想象 InnoDB 是一个高效运转的仓库: 核心内存区 (大脑 & 高速缓存 - 干活超快的地方) 缓冲池 Buffer Pool (最最核心!): 作用: 相当于仓库的“高频货架”。把最常用的数据(表数据、索引)从…

第4讲、Odoo 18 模块系统源码全解与架构深度剖析【modules】

引言 Odoo 是一款强大的开源企业资源规划(ERP)与客户关系管理(CRM)系统,其核心竞争力之一在于高度模块化的架构设计。模块系统不仅是 Odoo 框架的基石,更是实现功能灵活扩展与定制的关键。本文将结合 Odoo…

pytorch简单线性回归模型

模型五步走 1、获取数据 1. 数据预处理 2.归一化 3.转换为张量 2、定义模型 3、定义损失函数和优化器 4、模型训练 5、模型评估和调优 调优方法 6、可视化(可选) 示例代码 import torch import torch.nn as nn import numpy as np import matplot…

四、web安全-行业术语

1. 肉鸡 所谓“肉鸡”是一种很形象的比喻,比喻那些可以随意被我们控制的电脑,对方可以是WINDOWS系统,也可以是UNIX/LINUX系统,可以是普通的个人电脑,也可以是大型的服务器,我们可以象操作自己的电脑那样来…

Unity基础学习(十二)Unity 物理系统之范围检测

目录 一、关于范围检测的主要API: 1. 盒状范围检测 Physics.OverlapBox 2. 球形范围检测 Physics.OverlapSphere 3. 胶囊范围检测 Physics.OverlapCapsule 4. 盒状检测 NonAlloc 版 5. 球形检测 NonAlloc 版 6. 胶囊检测 NonAlloc 版 二、关于API中的两个重…

JVM 的垃圾回收机制 GC

C/C 这样的编程语言中,申请内存的时候,是需要用完了,进行手动释放的 C 申请内存 1)局部变量(不需要手动释放) 2)全局变量(不需要手动释放) 3)动态申请 malloc(通过 free 进行释放的) C 申请内存 1)局部变量 2)全局变量/静态变量 3)动态申请 new 通过 delete 进行释放 …

路由器、网关和光猫三种设备有啥区别?

无论是家中Wi-Fi信号的覆盖,还是企业网络的高效运行,路由器、网关和光猫这些设备都扮演着不可或缺的角色。然而,对于大多数人来说,这三者的功能和区别却像一团迷雾,似懂非懂。你是否曾疑惑,为什么家里需要光…

vscode实时预览编辑markdown

vscode实时预览编辑markdown 点击vsode界面,实现快捷键如下: 按下快捷键 CtrlShiftV(Windows/Linux)或 CommandShiftV(Mac)即可在侧边栏打开 Markdown 预览。 效果如下:

2505软考高项第一、二批真题终极汇总

第一批2025.05综合题(75道选择题) 1、2025 年中央一号文件对进一步深化农村改革的各项任务作出全面部署。“推进农业科技力量协同攻关”的相关措施不包括()。 A.强化农业科研资源力量统筹,培育农业科技领军企业 B.发挥农业科研平台作用&…

云原生安全基础:Linux 文件权限管理详解

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 在云原生环境中,Linux 文件权限管理是保障系统安全的核心技能之一。无论是容器化应用、微服务架构还是基础设施即代码(IaC&#xf…

[嵌入式实验]实验二:LED控制

一、实验目的 1.熟悉开发环境 2.控制LED灯 二、实验环境 硬件:STM32开发板、CMSIS-DAP调试工具 软件:ARM的IDE:Keil C51 三、实验内容 1.实验原理 (1)LED灯原理与点亮 LED即发光二极管,有电流通过…

6.4.2_3最短路径问题_Floyd算法

Floyd弗洛伊德 膜拜大佬,给大佬鞠躬鞠躬鞠躬。。。。。。。。。 Floyd算法 ----解决顶点间的最短路径: 过程: 如下: 初始化(没有中转点):2个邻接矩阵A和path,第一个是没有中转点的2个顶点之间的最短路径…

<PLC><socket><西门子>基于西门子S7-1200PLC,实现手机与PLC通讯(通过websocket转接)

前言 本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。 PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。 除了PLC为主要内容外,PLC相关元器件如触摸屏(HMI)、交换机等工控产品,如…

深度学习核心网络架构详解(续):从 Transformers 到生成模型

在上一篇文章中,我们详细介绍了卷积神经网络 (CNN)、循环神经网络 (RNN) 及其变体 LSTM 和 GRU。本文将继续探讨其他必须掌握的深度学习网络架构,包括 Transformers、生成对抗网络 (GAN)、自编码器 (Autoencoder) 以及强化学习基础。我们将深入讲解这些技…

AI智能混剪视频大模型开发方案:从文字到视频的自动化生成·优雅草卓伊凡

AI智能混剪视频大模型开发方案:从文字到视频的自动化生成优雅草卓伊凡 引言:AI视频创作的未来已来 近年来,随着多模态大模型(如Stable Diffusion、Sora、GPT-4)的爆发式发展,AI已经能够实现从文字生成图像…