JVM之【运行时数据区1】

news2025/2/26 14:24:35

JVM简图

在这里插入图片描述

运行时数据区简图

运行时数据区

一、程序计数器(Program Counter Register)

1.程序计数器是什么?

程序计数器是JVM内存模型中的一部分,它可以看作是一个指针,指向当前线程所执行的字节码指令的地址。每个线程在执行过程中都有自己的程序计数器,因此程序计数器是线程私有的,独立于其他线程。

程序计数器不会OOM!!!

2.程序计数器的作用

  1. 指令执行:在每个线程执行字节码指令时,程序计数器会存储当前正在执行的字节码指令的地址。如果是正在执行本地方法(native method),那么程序计数器的值将是undefined。

  2. 指令跳转:在字节码指令执行完毕后,程序计数器会自动更新为下一条要执行的字节码指令的地址。通过这种方式,程序计数器可以确保字节码指令按顺序执行。

  3. 控制流管理:程序计数器帮助管理程序的控制流(如分支、循环、跳转等)。通过更新程序计数器的值,可以实现各种控制流指令(如if、for循环、switch等)的跳转逻辑。

  4. 多线程切换:由于Java是多线程的语言,每个线程都有自己独立的程序计数器。当线程切换时,程序计数器会保存当前线程的执行位置,当线程再次被调度时,程序计数器会恢复到之前保存的位置,以确保线程可以继续从正确的位置执行。


二、虚拟机栈(Java Virtual Machine Stack)

在Java虚拟机(JVM)中,每个线程在创建时都会创建一个虚拟机栈,虚拟机栈是每个线程私有的数据区,用于管理方法调用和执行。其内部保存一个个的栈帧(Stack Frame),对应着一次次的Java方法调用。每当一个线程调用一个方法时,JVM会为该方法创建一个新的栈帧(Stack Frame)并将其压入虚拟机栈中,方法执行完毕后,栈帧会从栈中弹出。

**存在OOM,但是不需要垃圾回收**

在这里插入图片描述

如何设置栈大小

-Xss:一般默认大小为1024KB
单位为bytes,还可以使用KB/MB/GB单位进行设置

栈帧(Stack Frame)

1、JVM直接对Java栈的操作只有两个,就是对栈帧的压栈和出栈,遵循“先进后出”/“后进先出”原则。在一条活动线程中,一个时间点上,只会有一个活动的栈帧。
2、只有当前正在执行的方法的栈帧(栈顶栈帧)是有效的,这个栈被称为当前栈帧(Current Frame),与当前栈帧相对应的方法就是当前方法(CurrentMethod),定义这个方法的类就是当前类(CurrentClass)。
3、执行引擎运行的所有字节码指令只针对当前栈帧进行操作。如果在该方法中调用了其他方法,对应的新的栈帧会被创建出来,放在栈的顶端,成为新的当前帧。
4、方法嵌套调用的极限次数,由栈的大小决定。超过大小时就会溢出OOM

在这里插入图片描述

1.栈帧的组成部分

  1. 局部变量表(Local Variable Array/Table)
  2. 操作数栈(Operand Stack)
  3. 动态链接(Dynamic Linking)
  4. 方法返回地址(Return Address)
  5. 附加信息(Additional Information)
    在这里插入图片描述

2.详细描述

1. 局部变量表(Local Variable Array/Table)
  • 原理
    • 局部变量表是一个数组,用于存储方法的局部变量,包括方法参数和方法内部定义的变量。 这些数据类型包括各类基本数据类型、对象引用,以及返回地址。
    • 局部变量表是建立在线程的栈上,是线程私有数据,不存在数据安全问题。
    • 局部变量表的容量大小,实在编译期间确定下来的,并保存在方法的Code属性的maximum local variables数据项中。在方法运行期间是不会改变局部变量表的大小的。
    • 方法嵌套调用的极限次数,由栈的大小决定。参数和局部变量越多,使得局部变量表膨胀,栈帧就越大,就会导致嵌套调用次数减少。
    • 表中的变量,只在当前方法调用中有效。方法调用结束后,随着栈帧的销毁,局部变量表随之销毁。
  • 作用:为每个方法提供存储和访问局部变量的空间。局部变量通过索引进行访问,索引从0开始。例如,int a = 10; 中的 a 就存储在局部变量表中。
  • 存储信息:存储了方法的参数和方法内部定义的局部变量。可以存储各种数据类型,包括基本数据类型(int、float、long、double等)以及对象引用。

大概看一下局部变量表
在这里插入图片描述
局部变量表

1、上图中,这里的参数名称、参数类型中的cp_info#,就是符号名称/符号引用,指的就是常量池中的内容。
2、以int 变量 a 为例,19、20 就对应了变量a和int类型
3、需要注意,非静态方法的局部变量表中,第一个序号0一定为this,指向当前方法。静态方法则没有
4、序号是slot,32位的类型占用1个slot,64位的占用两个slot,所以这里的序号都是1递增。如果使用double变量,就会看到序号会+2
5、不足32位的按照32来算,其中byte、short、char、boolean都会被转换为int来储存

在这里插入图片描述

2. 操作数栈(Operand Stack)
  • 原理
    • 操作数栈是一个LIFO栈,用于字节码指令执行时的临时存储空间。
    • 栈的最大深度在编译期就定义好了。并保存在方法的Code属性的max_stack数据中。
    • 和局部变量表类似,在栈中,32位的类型占用1个深度,64位的占用两个深度
  • 作用:在方法执行过程中,用于保存中间计算结果、传递参数以及存储返回值。例如,执行加法操作 i + j 时,会将 ij 压入操作数栈,执行完加法操作后,将结果存储在操作数栈中。
  • 存储信息:方法执行过程中临时存储的操作数、中间计算结果。

举例
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 动态链接(Dynamic Linking)
  • 原理:每个栈帧包含指向运行时常量池中,该栈帧所属方法的引用,目的是为了支持当前方法的代码能够实现动态链接。
  • 作用
    • Java源文件倍编辑成字节码文件时,所有变量和方法引用,都作为符号引用,保存在常量池中(在上面局部变量表中,有截图)
    • 当一个方法调用另外其他方法时,动态链接会将符号引用转换为实际的方法内存地址。
      在这里插入图片描述
(1)静态链接和动态链接
  • 静态链接:
    当一个字节码文件被装载进JVM内部时,如果被调用的目标方法在编译期可知且运行期保持不变时。这种情况下将调用方法的符号引用转换为直接引用的过程称之为静态链接。
  • 动态链接:
    如果被调用的方法在编译期无法被确定下来,也就是说,只能够在程序运行期将调用方法的符号引用转换为直接引用,由于这种引用转换过程具备动态性,因此也就被称之为动态链接。
(2)早期绑定和晚期绑定

对应的方法的绑定机制为:早期绑定(EarlyBinding)和晚期绑定(Late Binding)。绑定是一个字段、方法或者类在符号引用被替换为直接引用的过程,这仅仅发生一次。

  • 早期绑定:
    早期绑定就是指被调用的目标方法如果在编译期可知,且运行期保持不变时即可将这个方法与所属的类型进行绑定,这样一来,由于明确了被调用的目标方法究竟是哪一个,因此也就可以使用静态链接的方式将符号引用转换为直接引用。
  • 晚期绑定
    如果被调用的方法在编译期无法被确定下来,只能够在程序运行期根据实际的类型绑定相关的方法,这种绑定方式也就被称之为晚期绑定。

** 这里主要还是针对多态的 **

4. 方法返回地址(Return Address)
  • 原理
    • 在方法调用时,返回地址会记录调用方法的指令地址,以便方法返回时能找到正确的返回位置。
    • 方法返回有两类:正常完成、异常退出
    • 正常返回时,会调用方法的下一条指令
    • 异常退出时,需要通过异常表来确定,栈帧不保存相关信息
  • 作用:方法执行完毕后,返回到调用该方法的地方继续执行。这个地址一般是调用方法的下一条指令。
  • 本质上,方法的退出就是当前栈帧出栈的过程。此时,需要恢复上层方法的局部变量表、操作数栈、将返回值压入调用者栈帧的操作数栈、设置PC寄存器值等,让调用者方法继续执行下去。
  • 正常完成出口和异常完成出口的区别在于:通过常完成出口退出的不会给他的上层调用者产生任何的返回值。
5. 附加信息(Additional Information)
  • 原理:附加信息因JVM实现而异,包括栈帧的一些其他信息,比如调试信息和性能分析信息。
  • 作用:为JVM提供更多的运行时信息支持,如异常处理信息、JVM优化信息等。

课后问答

  1. 举例栈溢出的情况?(StackOverflowError)
  2. 调整栈大小,就能保证不出现溢出吗?
  3. 分配的栈内存越大越好吗?
  4. 垃圾回收是否会涉及到虚拟机栈?
  5. 方法中定义的局部变量是否线程安全?

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

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

相关文章

基础—SQL—DQL(数据查询语言)排序查询

一、引言 排序查询这里面涉及的关键字:ORDER BY。在我们日常的开发中,这个是很常见的,比如打开一个网购的商城,这里面可以找到一个销量的排序、综合的排序、价格的排序(升序、降序)等等。接下来就学习这一部…

前端传String字符串 后端使用enun枚举类出现错误

情况 前端 String 后端 enum 前端 后端 报错 2024-05-31T21:47:40.61808:00 WARN 21360 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to con…

《QT实用小工具·六十九》基于QT开发的五子棋AI游戏

1、概述 源码放在文章末尾 该项目实现了五子棋对战AI,可以享受和AI下棋的快乐,项目实现思路如下: 博弈树 ●Alpha-Beta剪枝(性能提高较大) ●启发式搜索(性能提高较大) ●落子区域限制(性能提高较大) ●Zobrist哈希(性能小幅提升) ●Qt…

【再探】设计模式—访问者模式、策略模式及状态模式

访问者模式是用于访问复杂数据结构的元素,对不同的元素执行不同的操作。策略模式是对于具有多种实现的算法,在运行过程中可动态选择使用哪种具体的实现。状态模式是用于具有不同状态的对象,状态之间可以转换,且不同状态下对象的行…

记mapboxGL实现鼠标经过高亮时的一个问题

概述 mapboxGL实现鼠标经过高亮可通过注册图层的mousemove和moveout事件来实现,在mousemove事件中可以拿到当前经过的要素,但是当使用该要素时,发现在某个地图级别下会有线和面数据展示不全的情况。究其原因,发现是mapboxGL在绘图…

2024Dragon Knight CTF复现web

穿梭隐藏的密钥 首先看看页面的源代码,但是发现f12和鼠标右键都被禁用了 用ctrlu查看,发现一个可疑页面 访问看看,发现还是只有一张图,查看源代码发现提示 扩展: Fuzz:Fuzz是一种基于黑盒的自动化软件模糊…

数据结构与算法笔记:基础篇 - 栈:如何实现浏览器的前进和后退功能?

概述 浏览器的前进、后退功能,你肯定很熟悉吧? 当依次访问完一串页面 a-b-c 之后,点击浏览器的后退按钮,就可以查看之前浏览过的页面 b 和 a。当后退到页面 a,点击前进按钮,就可以重新查看页面 b 和 c。但…

C/S模型测试

1 1.1代码示例 #include<stdio.h> #include<stdio.h>#include <sys/types.h> /* See NOTES */ #include <sys/socket.h>#include <netinet/in.h> #include <netinet/ip.h> /* superset of previous */ #include <arpa/inet.…

004 仿muduo实现高性能服务器组件_Buffer模块与Socket模块的实现

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;仿muduo &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多知识 文章目录 前言Buffer模块Socket模块 小结 前言 这章将会向你介绍仿muduo高性能服务器组件的buffer模块与socket模块的实…

12k Star!Continue:Github Copilot 开源本地版、开发效率和隐私保护兼得、丰富功能、LLM全覆盖!

原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; 12k Star&#xff01;Continue&#xff1a;Github Copilot 开源本地版、开发效率和隐私保护兼得、丰富功能、LLM全覆盖&#xff01; &…

CSS--学习

CSS 1简介 1.1定义 层叠样式表 (Cascading Style Sheets&#xff0c;缩写为 CSS&#xff09;&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#xff09;。 1.2 特性 继承性 子级默认继承父级的文字控制属性。层叠性 相同的属性…

Elasticsearch 认证模拟题 - 5

一、题目 .在集群上有一个索引 food_ingredient&#xff0c;搜索需要满足以下要求&#xff1a; 三个字段 manufacturer&#xff0c;name&#xff0c;brand 都能匹配到文本 cake mix高亮 字段 name&#xff0c;并加标签排序&#xff0c;对字段 brand 正序&#xff0c;_score 降…

【Linux】Linux环境基础开发工具_3

文章目录 四、Linux环境基础开发工具2. vim3. gcc和g动静态库的理解 未完待续 四、Linux环境基础开发工具 2. vim vim 怎么批量化注释呢&#xff1f;最简单的方法就是在注释开头和结尾输入 /* 或 */ 。当然也可以使用快捷键&#xff1a; Ctrl v 按 hjkl 光标移动进行区域选择…

VR导航的实现原理、技术优势和应用场景

VR导航通过虚拟现实技术提供沉浸式环境&#xff0c;结合室内定位技术实现精准导航。目前&#xff0c;VR导航已在多个领域展现出其独特的价值和潜力&#xff0c;预示着智能导航系统的未来发展。 一、实现原理 VR导航技术依托于虚拟现实(VR)和室内定位系统。VR技术利用计算机模…

IMU状态预积分代码实现 —— IMU状态预积分类

IMU状态预积分代码实现 —— IMU状态预积分类 实现IMU状态预积分类 实现IMU状态预积分类 首先&#xff0c;实现预积分自身的结构。一个预积分类应该存储一下数据&#xff1a; 预积分的观测量 △ R ~ i j , △ v ~ i j , △ p ~ i j \bigtriangleup \tilde{R} _{ij},\bigtrian…

MySQL基础索引知识【索引创建删除 | MyISAM InnoDB引擎原理认识】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;MySQL之旅_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一&#xff0c;索引用…

数据在内存中的存储<C语言>

导言 在计算机中不同类型的数据在计算机内部存储形式各不相同&#xff0c;弄懂各种数据在计算机内部存储形式是有必要的&#xff0c;C语言的学习不能浮于表面&#xff0c;更要锻炼我们的“内功”&#xff0c;将来在写程序的时候遇见各种稀奇古怪的bug时&#xff0c;也便能迎刃而…

Beamer中二阶导、一阶导数的显示问题

Beamer中二阶导、一阶导数的显示问题 在beamer中表示 f ′ f f′和 f ′ ′ f f′′时发现导数符号距离 f f f很近 \documentclass{beamer} \usepackage{amsmath,amssymb}\begin{document} \begin{frame}\frametitle{Derivative}Derivative:\[f^{\prime}(x) \quad f \quad…

4月啤酒品类线上销售数据分析

近期&#xff0c;中国啤酒行业正处于一个重要的转型期。首先&#xff0c;消费者对高品质啤酒的需求不断增加&#xff0c;这推动了行业向高端化、场景化和社交化的方向发展。精酿啤酒作为这一趋势的代表&#xff0c;其发展势头强劲&#xff0c;不仅满足了消费者对品质化、个性化…

Java集合【超详细】2 -- Map、可变参数、Collections类

文章目录 一、Map集合1.1 Map集合概述和特点【理解】1.2 Map集合的基本功能【应用】1.3 Map集合的获取功能【应用】1.4 Map集合的两种遍历方式 二、HashMap集合2.1 HashMap集合概述和特点【理解】2.2 HashMap的组成、构造函数2.3 put、查找方法2.4 HashMap集合应用案例【应用】…