Java虚拟机 - 程序计数器和虚拟机栈

news2025/5/25 17:46:16

运行时数据结构

  • Java运行时数据区
    • 程序计数器
    • 为什么需要程序计数器
    • 执行流程
    • 虚拟机栈
      • 虚拟机栈作用
      • 虚拟机栈核心结构
      • 运行机制

Java运行时数据区

首先介绍Java运行时数据之前,我们要了解,对于计算机来说,内存是非常重要的资源,因为内存是连接CPU与硬盘的桥梁,承载着操作系统与应用程序的运行的基础。JVM在运行期间把它管理的内存分为若干个区域,有些区域是线程私有的,有些区域是共享的。
Java运行时数据区作为JVM在程序执行过程中管理内存的核心结构,主要包括方法区(存储类元数据、运行时常量池、静态变量)、堆(存放对象实例和数组,被所有线程共享且是垃圾回收的主区域)、虚拟机栈(每个线程私有,用于存储方法调用的栈帧,包含局部变量表、操作数栈及方法出口)、本地方法栈(支持Native方法调用)和程序计数器(记录当前线程执行的字节码位置,确保多线程切换后能恢复执行)。其中,堆和方法区是线程共享的,而虚拟机栈、本地方法栈和程序计数器为线程私有,共同协作实现Java程序的内存分配、方法执行及多线程调度。
在这里插入图片描述

程序计数器

程序计数器(Program Counter Register)在JVM中可以当成当前线程所执行的字节码的行号指示器,在JVM的概念模型里面,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器。分支 、循环 、跳转 、异常处理 、线程恢复等都是依赖这个计数器来实现的。
在这里插入图片描述
如果程序执行的是Java方法,计数器代表的是只在执行的虚拟机字节码的地址;如果执行的是本地方法,这个计数器的值为空(undefined)。此外,这个计数器区域是Java虚拟机规范的没有规定任何内存溢出的地方,程序计数区既没有内存溢出,也没有垃圾回收。因为程序计数器是很小的一块内存区域,几乎可以忽略不记,同时也是运行最快的区域。

为什么需要程序计数器

因为CPU需要不停的切换各个线程,做完切换之后,需要知道接下来从哪里开始执行。通过使用程序计数器保存了接下来要执行的地址,这样CPU切换过来之后就可以直接接着执行。

执行流程

// 示例代码
public class Demo {


    public int test() {
        int a = 10;
        int b = 20;
        int c = a + b;
        String d = "abd";
        System.out.println(d);
        return d.length();
    }
}

通过javap -c Demo.class反编译后:

 0 bipush 10
 2 istore_1
 3 bipush 20
 5 istore_2
 6 iload_1
 7 iload_2
 8 iadd
 9 istore_3
10 ldc #2 <abd>
12 astore 4
14 getstatic #9 <java/lang/System.out : Ljava/io/PrintStream;>
17 aload 4
19 invokevirtual #15 <java/io/PrintStream.println : (Ljava/lang/String;)V>
22 aload 4
24 invokevirtual #21 <java/lang/String.length : ()I>
27 ireturn

在这里插入图片描述

虚拟机栈

虚拟机栈(Java Virtual Machine Stack)是JVM内存模型中与线程执行密切相关的核心区域,用于存储方法调用的栈帧(Stack Frame)。它是线程私有的内存空间,每个线程在创建时都会分配一个独立的虚拟机栈,其生命周期与线程一致。以下从设计目标、核心结构、运行机制到常见问题全面解析。

虚拟机栈作用

虚拟机栈的核心功能是支持Java方法的调用与执行,具体包括:

  • 方法调用链管理:保存方法的调用顺序(如 main() → methodA() → methodB())。

  • 局部变量存储:存储方法内的基本类型变量、对象引用。

  • 操作数计算:提供临时数据存储空间(如算术运算的中间结果)。

  • 方法返回控制:记录方法执行完成后的返回地址。

虚拟机栈核心结构

虚拟机栈由多个栈帧(Stack Frame)构成,每个栈帧对应一个方法的调用。栈帧包含以下核心部分:

  1. 局部变量表(Local Variables Table)
    作用:存储方法参数和方法内定义的局部变量。

     结构:
    
     		以变量槽(Slot)为最小单位,每个Slot占用32位(long和double占2个Slot)。
    
     		索引从0开始,依次存放this(非静态方法)、方法参数、局部变量。
    
    
     示例:
    
public void demo(int a, String b) {
    double c = 3.14;
    Object d = new Object();
}
局部变量表结构:

在这里插入图片描述

  1. 操作数栈(Operand Stack)

    作用:保存计算过程中的临时数据(类似CPU的寄存器)。

    特点:

     深度在编译期确定(写入方法表的max_stack属性)。
    
     通过iconst_1、iadd等字节码指令操作栈顶元素。
    
int result = 1 + 2;
iconst_1  // 压入1
iconst_2  // 压入2
iadd      // 弹出1和2,相加后压入3
istore_1  // 将3存储到局部变量表索引1
  1. 动态链接(Dynamic Linking)
  • 作用:将符号引用(如com/example/Demo.methodA)转换为直接引用(内存地址)。

  • 意义:支持多态特性(如接口方法、虚方法调用)。

  • 对比:

    • 静态解析:类加载阶段可确定的直接引用(如final方法)。

    • 动态链接:运行时才能确定(如重写方法)。

  1. 方法返回地址(Return Address)
    作用:记录方法正常结束或异常退出后的返回位置。
    两种返回方式:
  • 正常返回(return指令):程序计数器恢复为调用者的下一条指令地址。

  • 异常退出:通过异常处理器表(Exception Table)确定跳转地址。

运行机制

  1. 方法调用与栈帧压栈
    调用方法时:创建新栈帧并压入栈顶。

方法返回时:栈帧弹出,释放内存。

  1. 栈溢出(StackOverflowError)
    触发条件:线程请求的栈深度超过JVM允许的最大值(如无限递归)。

示例:

public class StackOverflowDemo {
    public static void main(String[] args) {
        infiniteCall(); // 无限递归调用
    }
    static void infiniteCall() {
        infiniteCall();
    }
}

报错信息:

Exception in thread "main" java.lang.StackOverflowError
  1. 栈大小配置
    参数:-Xss(如-Xss1m设置栈大小为1MB)。

默认值:不同JVM实现不同(HotSpot Linux x64默认1MB)。

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

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

相关文章

新能源汽车产业链图谱分析

1. 产业定义 新能源汽车是指采用非常规的车用燃料作为动力来源&#xff0c;综合车辆的动力控制和驱动方面的先进技术&#xff0c;形成的具有新技术、新结构、技术原理先进的汽车。 新能源车包括四大类型&#xff1a;混合动力电动汽车&#xff08;HEV&#xff09;、纯电动汽车…

如何在PyCharm2025中设置conda的多个Python版本

前言 体验的最新版本的PyCharm(Community)2025.1.1&#xff0c;发现和以前的版本有所不同。特别是使用Anaconda中的多个版本的Python的时候。 关于基于Anaconda中多个Python版本的使用&#xff0c;以及对应的Pycharm&#xff08;2023版&#xff09;的使用&#xff0c;可以参考…

maven快速上手

之前我们项目如果要用到其他额外的jar包&#xff0c;需要自己去官网下载并且导入。但是有maven后&#xff0c;直接在maven的pom.xml文件里用代码配置即可&#xff0c;配置好后maven会自动帮我们联网下载并且会自动导入该jar包 在右边的maven中&#xff0c;我们可以看到下载安装…

cplex12.9 安装教程以及下载

cplex 感觉不是很好找&#xff0c;尤其是教育版&#xff0c;我这里提供一个版本&#xff0c;在下面的图可以看到&#xff0c;不仅可以配置matlab&#xff0c;也可以配置vs,现在拿vs2017来测试一下&#xff0c;具体文件的文件有需要的可以复制下面的链接获取 我用网盘分享了「c…

甘特图实例 dhtmlxGantt.js

本文介绍了如何使用dhtmlxGantt库创建一个基础的甘特图示例&#xff0c;并对其进行汉化和自定义配置。首先&#xff0c;通过引入dhtmlxgantt.css和dhtmlxgantt.js文件初始化甘特图。接着&#xff0c;通过设置gantt.i18n.setLocale("cn")实现核心文本的汉化&#xff0…

视频剪辑 VEGAS - 配置视频片段保持原长宽比

VEGAS 配置视频片段保持原长宽比 右击视频片段 -> 选择【开关】 -> 勾选【保持长宽比】 右击视频片段 -> 点击【属性】 -> 弹出【属性】窗口 点击【媒体】 -> 选择【像素宽高比】为【1,0000&#xff08;方形&#xff09;】

力扣 54 .螺旋矩阵

文章目录 题目介绍题解 题目介绍 题解 代码如下&#xff1a; class Solution {public List<Integer> spiralOrder(int[][] matrix) {List<Integer> res new ArrayList<>();if (matrix.length 0){return res;}int l 0, r matrix[0].length - 1, t 0, b…

四、【API 开发篇 (上)】:使用 Django REST Framework 构建项目与模块 CRUD API

【API 开发篇 】&#xff1a;使用 Django REST Framework 构建项目与模块 CRUD API 前言为什么选择 Django REST Framework (DRF)&#xff1f;第一步&#xff1a;创建 Serializers (序列化器)第二步&#xff1a;创建 ViewSets (视图集)第三步&#xff1a;配置 URLs (路由)第四步…

ARM笔记-ARM伪指令及编程基础

第四章 ARM伪指令及编程基础 4.1 伪指令概述 4.1.1 伪指令定义 人们设计了一些专门用于指导汇编器进行汇编工作的指令&#xff0c;由于这些指令不形成机器码指令&#xff0c;它们只是在汇编器进行汇编工作的过程中起作用&#xff0c;所以被叫做伪指令。 4.1.2 伪指令特征 …

Python入门手册:Python基础语法

Python是一种简洁、易读且功能强大的编程语言&#xff0c;非常适合初学者入门。无论你是编程新手&#xff0c;还是有一定编程基础但想学习Python的开发者&#xff0c;掌握Python的基础语法都是迈向高效编程的第一步。本文将详细介绍Python的基本语法&#xff0c;包括变量和数据…

CAD如何导出PDF?PDF如何转CAD?详细教程来了

浩辰CAD看图王是一款功能强大的CAD图纸查看与编辑工具&#xff0c;其核心功能之一便是支持CAD与PDF格式的互转。下面是CAD看图王输出PDF和PDF转CAD功能的详细介绍及操作步骤&#xff1a; 一、输出PDF功能 看图王可以将CAD图纸转换为PDF格式&#xff0c;是文件在不同的设备上显…

python-数据可视化(大数据、数据分析、可视化图像、HTML页面)

通过 Python 读取 XLS 、CSV文件中的数据&#xff0c;对数据进行处理&#xff0c;然后生成包含柱状图、扇形图和折线图的 HTML 报告。这个方案使用了 pandas 处理数据&#xff0c;matplotlib 生成图表&#xff0c;并将图表嵌入到 HTML 页面中。 1.XSL文件生成可视化图像、生成h…

【笔记】OpenCV的学习(未完)

由于只记关键和不懂的部分 希望做到下次再看这部分笔记就记得 所以用词会非常简练 前向传播 输入数据依次经过模型的各层&#xff0c;按照各层定义的运算规则进行计算&#xff0c;最终得到模型预测输出的过程。 单向的信息流动&#xff0c;不涉及模型参数的更新。 助于思考的…

多模态大语言模型arxiv论文略读(八十七)

MG-LLaVA: Towards Multi-Granularity Visual Instruction Tuning ➡️ 论文标题&#xff1a;MG-LLaVA: Towards Multi-Granularity Visual Instruction Tuning ➡️ 论文作者&#xff1a;Xiangyu Zhao, Xiangtai Li, Haodong Duan, Haian Huang, Yining Li, Kai Chen, Hua Ya…

记录将网站从http升级https

http与https 你知道http是什么吗&#xff0c;那你知道https吗&#xff1f;在进行升级之前我们应该都听说http不安全&#xff0c;要用https&#xff0c;那你知道这是为什么吗&#xff1f; 什么是http&#xff1f; HTTP 是超文本传输协议&#xff0c;也就是HyperText Transfer…

免费PDF工具-PDF24V9.16.0【win7专用版】

【百度】https://pan.baidu.com/s/1H7kvHudG5JTfxHg-eu2grA?pwd8euh 提取码: 8euh 【夸克】https://pan.quark.cn/s/92080b2e1f4c 【123】https://www.123912.com/s/0yvtTd-XAHjv https://creator.pdf24.org/listVersions.php

一周学会Pandas2 Python数据处理与分析-Pandas2数据合并与对比-pd.concat():轴向拼接

锋哥原创的Pandas2 Python数据处理与分析 视频教程&#xff1a; 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 在数据分析中&#xff0c;数据往往分散在多个来源&#xff08;如不同文件、数据库表或API&#xff09;&#xff0c;需…

安卓原生兼容服务器

安卓原生兼容服务器的定义 安卓原生兼容服务器‌指基于Android系统内核和服务框架构建的服务器环境&#xff0c;能够在不依赖第三方适配层的情况下&#xff0c;直接运行符合Android API规范的服务程序&#xff0c;并满足与其他软硬件组件的协同工作需求。其核心特征体现在以下…

优化用户体验:拦截浏览器前进后退、刷新、关闭、路由跳转等用户行为并弹窗提示

&#x1f9d1;‍&#x1f4bb; 写在开头 点赞 收藏 学会&#x1f923;&#x1f923;&#x1f923; 需求 首先列举一下需要拦截的行为&#xff0c;接下来我们逐个实现。 浏览器前进后退标签页刷新和关闭路由跳转 1、拦截浏览器前进后退 这里的实现是核心&#xff0c;涉及到大…

大学生创新创业项目管理系统设计——数据库实验九

本实验为自己设计完成&#xff0c;我当年数据库实验得了94分 目录 1.实验目的 2.实验内容和要求 3.实验步骤 4.实验心得 实验九 数据库设计 1.实验目的 掌握数据库设计的过程和方法。 2.实验内容和要求 &#xff08;35&#xff09;大学生创新创业项目管理系统设计 一…