Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JVM深入原理(七)(一):运行时数据区

JVM深入原理(七)(一):运行时数据区

作者头像
摘星.
发布于 2025-05-20 06:11:33
发布于 2025-05-20 06:11:33
520
举报
文章被收录于专栏:博客专享博客专享

7. JVM运行时数据区

7.1. 运行时数据区-总览

  • 运行时数据区的概念:是JVM运行Java程序过程中管理内存的区域
  • 运行时数据区的组成总览
  • 线程不共享的含义:每个线程创建后,内部都会创建自己的程序计数器,Java虚拟机栈,本地方法栈对应的数据,自己维护数据,不共享,安全性高,当线程回收时这些区域的内存也随着回收
  • 线程共享的含义:每个线程都可以访问方法区和堆中的数据,是共享的,是线程不安全的

7.2. 运行时数据区-查看内存对象

  • JDK自带的hsdb工具查看JVM内存信息,工具位于JDK安装目录下lib文件夹中的sa-jdi.jar文件中
  • 启动命令:java -cp sa-jdi.jar sun.jvm.hotspot.HSDB

7.3. 运行时数据区-程序计数器

7.3.1. 程序计数器-作用
  • 程序计数器的作用:程序计数器(Program Counter Register)也叫PC寄存器,内部存放了接下来要执行的字节码指令的地址,交给解释器执行,可以实现分支,跳转,异常等逻辑,在多线程情况下,JVM需要程序计数器记录CPU切换前的地址并继续执行,程序计数器只存储一个固定长度的内存地址,不会内存溢出
7.3.2. 字节码指令执行流程
  • 字节码指令执行的流程:字节码指令和偏移量最初保存在字节码文件中,类加载器将字节码文件读取到内存之后,字节码指令也就保存在内存中原文件中的偏移量也被替换成内存地址,每一行字节码指令都有自己的地址,字节码指令最终要交给解释器去执行,所以解释器就必须知道需要解释的字节码指令在哪,这个地址就由程序计数器交给解释器

程序计数器在物理上的实现是寄存器,是整个CPU里读取速度最快的单元

程序计数器也就是Java对物理硬件的屏蔽和抽象

7.4. 运行时数据区-Java虚拟机栈

7.4.1. 栈-概述
  • 栈的介绍:Java虚拟机栈采用栈的数据结构来管理方法调用中的基本数据,先进后出,每一个方法的调用使用一个栈帧来保存
  • 栈的组成:
    • 栈:一个线程运行所需要的内存空间,一个栈由多个栈帧组成
    • 栈帧:一个方法运行所需要的内存空间
      • 活动栈帧:一个线程中只能有一个活动栈帧
  • 栈的生命周期:栈随着线程的创建而创建,而回收会在线程销毁时进行
  • 栈的执行流程:
    1. 栈帧压入栈内执行方法
    2. 执行完毕释放内存
    3. 若方法间存在调用,那么会压入被调用方法入栈,执行完后释放内存,再执行当前方法,直到执行完毕,释放所有内存
7.4.2. 栈帧-组成
7.4.2.1. 栈帧-帧数据
  • 帧数据的作用:包含动态链接,方法出口,异常表的引用
    • 动态链接:保存的是符号引用到内存地址的映射关系,主要保存的是其他类的属性或方法,字节码指令运行时可以根据动态链接快速获取到运行时常量池的数据
    • 方法出口:方法出口指的是方法在正确或者异常结束时,当前栈帧会被弹出,同时程序计数器应该指向上一个栈帧中的下一条指令的地址。所以在当前栈帧中,需要存储此方法出口的地址
    • 异常表:异常表存放的是代码中异常的处理信息,包含了try代码块和catch代码块执行后跳转到的字节码指令位置。
7.4.2.2. 栈帧-操作数栈
  • 操作数栈作用:存储方法执行过程中需要计算的操作数以及操作结果.
    • 计算过程:从操作数栈中弹出操作数、执行运算操作,并将结果重新压入操作数栈中
  • 操作数栈的生命周期:当方法执行时,创建一个对应的栈帧,栈帧中包括了该方法操作数栈,当方法执行结束时,对应的栈帧也会被销毁,在编译期就可以确定操作数栈的最大深度
7.4.2.3. 栈帧-局部变量表
  • 局部变量表的作用:存储方法执行过程中所有的局部变量,字节码文件编译时就确定了局部变量表的内容
  • 字节码文件中的局部变量表:每个局部变量表有编号和生效范围
  • 栈帧中的局部变量表:栈帧中的局部变量表是一个数组,数组中每一个位置称之为槽(slot),long和double类型占用两个槽,其他类型占用一个槽。
  • 局部变量表保存的内容:实例方法的this对象(0号位置),方法的参数,方法体中声明的局部变量。
  • 局部变量表的运行优化机制:局部变量表中的槽是可以复用的,一旦某个变量失效了(代码块中的变量执行完毕),当前槽就可以再次使用
  • 局部变量表的生命周期:当方法执行时,创建一个对应的栈帧,栈帧中包括了该局部变量表,当方法执行结束时,对应的栈帧也会被销毁
7.4.3. 栈-执行流程

执行流程演示:

  1. 栈内随着方法调用,栈帧一个个被压入栈内,随着方法执行完毕,方法一个个被弹栈而出,定义的变量的内存空间也随着方法执行完毕释放
7.4.4. 栈-内存溢出
  • 栈内存溢出的情况:Java虚拟机栈如果栈帧过多,占用内存超过栈内存可以分配的最大大小就会出现内存溢出,此时会出现StackOverflowError的异常
  • 栈帧过多:递归调用,死锁,死循环
  • 栈帧过大
7.4.5. 栈-设置栈内存大小
  • 设置栈大小参数:-Xss或-XX:ThreadStackSize=1024
    • 语法:-Xss栈大小或-XX:ThreadStackSize=栈大小
    • 单位:字节(默认,必须是1024的倍数)、k或者K(KB)、m或者M(MB)、g或者G(GB)
    • 栈最大最小值:jdk8中最大180k,最大1024mb
7.4.6. 栈相关问题
7.4.6.1. 垃圾回收是否涉及栈内存?

不涉及,每次方法执行完毕之后,栈内存就会直接释放,并不会堆积内存,垃圾回收的是堆内存中不使用的内存

7.4.6.2. 栈内存分配越大越好吗?

在程序执行时,可以通过-Xss size指定栈内存的大小,默认大小为1024KB也就是1M,一个线程使用一个栈内存,如果栈内存设置过大,那么单个线程占用的内存就会过大,在总内存空间一定的情况下,这样反而减少了线程数量,降低了性能

7.4.6.3. 方法内的局部变量是否线程安全?

要判定一个变量是否为线程安全,就要查看这个变量是为多个线程共有的还是一个线程私有的.

要判断方法中的成员变量是否为线程安全,要查看这个成员变量是否脱离了方法的作用范围,有两种情况是线程不安全的:

  • 变量作为参数传入方法中,这样其他线程就可能访问到该变量,所以不是线程安全的
  • 变量作为返回值返回,这样其他线程可能拿到该变量并操作,所以不是线程安全的
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JVM - 运行时数据区域(1)
Java 虚拟机在执行 Java 程序的过程中,会把它管理的内存划分成若干个不同的数据区域。
happyJared
2019/07/24
6150
JVM 系列(1) —— 运行时数据区域
Java 虚拟机会在 Java 运行程序的过程中把它所管理的内存分为若干个不同的数据区域
求和小熊猫
2020/12/16
2910
JVM 系列(1) —— 运行时数据区域
20张图助你了解JVM运行时数据区,你还觉得枯燥吗?
我们的JVM系列已经断更好几天了,小伙伴们在后台疯狂私信阿Q,想看后续内容,今天它来了。相信大家在上篇文章中已经对类加载子系统有了清晰的认识,接下来就让我们来揭开“运行时数据区”的神秘面纱吧。(文章可能有点长,建议先收藏一波)
阿Q说代码
2021/05/13
6850
20张图助你了解JVM运行时数据区,你还觉得枯燥吗?
JVM规范定义运行时数据区详解-Java快速进阶教程
内存是非常重要的系统资源,是硬盘和 CPU 的中间仓库及桥梁,承载着操作系统和应用程序的实时运行。JVM 内存布局规定了 Java 在运行过程中内存申请、分配、管理的策略,保证了 JVM 的高效稳定运行。不同的 JVM 对于内存的划分方式和管理机制存在着部分差异。Java 虚拟机规范定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些则是与线程一一对应的,这些与线程一一对应的数据区域会随着线程开始和结束而创建和销毁。
jack.yang
2025/04/05
780
JVM规范定义运行时数据区详解-Java快速进阶教程
动画:深度解析JVM运行时数据区 之 线程独占区
策划了很久了,一直在想用什么样的方式讲解知识点,能让大家一目了然,更容易的学到知识,并且还能加深记忆。思考良久,所以想到用动画的形式来展示。首次尝试,也希望大家多提出宝贵意见。后续可能会添加故事以及录音讲解的形式跟大家分享。
互扯程序
2020/05/19
1.2K0
JVM--运行时数据区
Java虚拟机在执行Java程序时,会把它所管理的内存划分为若干个数据区域,这些区域各有各的用途。
SuperHeroes
2019/03/12
4460
【云+社区年度征文】详解JVM运行时数据区
对于学过C++的开发者而言,他们对内存的分配与回收肯定不陌生,因为他们要对每一个对象负责(从创建到结束)。但是对于Java程序员来说,就不需要考虑那么多,因为虚拟机的内存管理机制可以帮助我们自动的管理内存,我们不再需要为每一个new操作去写配对的delete/free代码 。
Simon郎
2020/12/11
4960
堆、栈、方法区到底是什么?一文带你搞懂 JVM 运行时数据区内存模型!
在 JVM 的世界中,运行时数据区域是整个虚拟机的基础,它决定了程序的内存管理、线程的执行流以及垃圾回收的核心逻辑。
码哥字节
2024/11/26
5940
堆、栈、方法区到底是什么?一文带你搞懂 JVM 运行时数据区内存模型!
【JVM从小白学成大佬】2.Java虚拟机运行时数据区
这里我们先说句题外话,相信大家在面试中经常被问到介绍Java内存模型,我在面试别人时也会经常问这个问题。但是,往往都会令我比较尴尬,我还话音未落,面试者就会“背诵”一段(Java虚拟机是有堆、方法区、虚拟机栈,吧啦吧啦。。。),估计心里还一脸自豪的想幸好哥提前在网上搜过,早有准备。每每这个时候,我都不忍心打断,因为“背诵”的真的太顺畅了!
猿人谷
2020/01/21
3610
JVM运行时数据区
Java程序运行时JVM会把内存分为如下图所示的几个区域,其中包括线程所共享的堆、方法区以及线程所独有的虚拟机栈、本地方法栈和程序计数器。
你的益达
2020/08/05
3170
JVM运行时数据区
jvm入门2:3-5运行时数据区+程序技术器+虚拟机栈
内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行。jvm内存布局规定了java在运行过程中内存申请、分配、管理的策略,保证了jvm的高效稳定运行。不同的jvm对于内存的划分方式和管理机制存在着部分差异
用户10832809
2025/02/24
1110
一、JVM运行时数据区
JVM在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。
大数据程序猿
2020/09/08
3740
一、JVM运行时数据区
JVM-运行时数据区概述及虚拟机栈
每个线程:独立包括程序计数器、栈、本地栈 线程间共享:堆、堆外内存(永久代活元空间、代码缓存)
是小张啊喂
2022/08/18
4640
JAVA运行时数据区域
根据《Java 虚拟机规范(Java SE 7版)》规定,Java虚拟机所管理的内存将会包括一下几个运行时数据区域:
爱撸猫的杰
2019/03/28
5430
JAVA运行时数据区域
JVM笔记【1】-- 运行时数据区
C/C++每一个new操作都需要自己去delete/free,而java里面有虚拟机自动管理内存,不容易出现内存泄漏或者溢出的问题,但是不容易出现不代表不出现,了解虚拟机怎么使用和管理内存是十分重要的是,对程序优化或者问题排查有帮助。
秦怀杂货店
2020/12/26
2470
运行时数据区
JVM 只有一个方法区,且是被所有 JVM 线程共享的,方法区的生命周期是与 JVM 互相绑定的。方法区拥有以下特点:
DioxideCN
2023/01/13
2330
运行时数据区
JVM运行时数据区知多少
java引以为豪的就是内存自动化管理,不需要像C、C++等一样需要开发者手动获取内存、释放内存,对内存进行操作等,java在这方面做的非常好、非常方便。所以,了解java内存区域是怎么划分的是非常有必要的,面试的时候也是经常会问到的。
索码理
2022/12/28
3630
JVM运行时数据区知多少
JVM | 运行时数据区的JVM规范
在这一块的学习时, 我们容易陷入一个误区,就是一上来就直接搜索运行时数据区, 网上有些文章对虚拟机规范和HOTSPOT实现没有区分开,导致有时候大家看的两篇文章解释尽不一样. 自己也容易糊涂. 所以本篇特地将两个拆开讲. 且尽量以官方文档为准
微笑的小小刀
2020/02/17
7800
JVM(一)运行时数据区
由于JAVA程序是交由JVM执行的,所以我们所说的JAVA内存区域划分也是指的JVM内存区域划分,JAVA程序具体执行的过程如下图所示。首先Java源代码文件会被Java编译器编译为字节码文件,然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行。在整个程序执行过程中,JVM会用一段空间来存储程序执行期间需要用到的数据和相关信息,这段空间一般被称作为Runtime Data Area(运行时数据区),也就是我们常说的JVM内存。因此,在Java中我们常常说到的内存管理就是针对这段空间进行管理(如何分配和回收内存空间)。
周辰晨
2020/09/04
5320
JVM(一)运行时数据区
Java的运行时数据区域
Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间,有些区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。
真正的飞鱼
2023/04/02
5100
Java的运行时数据区域
相关推荐
JVM - 运行时数据区域(1)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档