网站首页 > java教程 正文
对于每个线程,JVM在创建线程时都会为其创建一个独立的栈空间。Java虚拟机栈的内存不需要是连续的。Java虚拟机仅直接对栈进行两种操作:压栈和弹出帧。每个特定线程的栈也可以称作运行时栈。该线程执行的每个方法调用,包括参数、局部变量、中间计算结果及其他数据,都会存储在对应的运行时栈中。完成一个方法后,相应的栈条目会被移除。当所有方法调用都完成后,栈变空,然后JVM会在线程结束前销毁这个空的栈。栈中存储的数据只能被相应线程访问,对于其他线程来说是不可见的,因此局部变量是线程安全的。栈中的每个条目被称为一个栈帧或激活记录。
栈帧结构
栈帧基本上由三部分构成:本地变量数组、操作数栈和帧数据。当JVM调用一个Java方法时,首先会检查类数据,确定该方法在本地变量数组和操作数栈中需要的字数(每个单独的方法的本地变量数组和操作数栈的大小以字为单位衡量)。然后,它会为被调用的方法创建一个大小适当的栈帧,并将其压入Java栈。
- 局部变量数组(LVA)
- 栈帧中的本地变量部分被组织为从零开始的字数组。
- 它包含了方法的所有参数和本地变量。
- 数组中的每个槽或条目是4字节。
- int、float和reference类型的值占用数组中的1个条目或槽,即4字节。
- double和long类型的值占用数组中的2个连续条目,即总共8字节。
- byte、short和char值在存储前会被转换为int类型,并且占用1个槽,即4字节。
- 但是存储布尔值的方式因JVM而异。不过大多数JVM为布尔值在本地变量数组中分配1个槽。
- 参数首先按宣布的顺序放入本地变量数组中。
例如:假设有一个名为Example的类,它有一个方法bike(),那么本地变量数组会如下图所示。
// Class Declaration
class Example
{
public void bike(int i, long l, float f,
double d, Object o, byte b)
{
}
}
- 操作数栈(OS)
JVM利用操作数栈作为工作区,就像使用草稿本一样,主要用来保存中间计算的结果。操作数栈的结构类似于本地变量数组,也是以字为单位排列的。但与通过索引访问本地变量数组不同的是,操作数栈是通过特定的指令来操作的,有的指令负责将数值推入栈中,有的指令负责将数值从栈中弹出,还有的指令执行所需的操作。
比如,当JVM执行下面的代码时,它会计算两个含有int类型数值的本地变量之差,并将结果作为int类型存储到第三个本地变量中:
所以,在这里,前两个指令iload_0和iload_1将会从本地变量数组中推送值到操作数栈中。然后isub指令将会减去这两个值,并把结果存回到操作数栈中。接着在istore_2之后,结果会从操作数栈中弹出,并存储到位置2的本地变量数组中。
- 帧数据(FD)
它包含了所有与特定方法相关的符号引用(常量池解析)和普通方法返回信息。
它还包含了对异常表的引用,这个异常表会在发生异常的情况下提供对应的catch块信息。
猜你喜欢
- 2024-11-12 本地方法栈、JVM栈、本地内存和JVM Heap的区别与关系
- 2024-11-12 Java基础之堆、栈、方法区、类加载器——JVM内存模型分析
- 2024-11-12 java之栈内存与堆内存(栈内存 和堆内存)
- 2024-11-12 深入了解Java虚拟机栈以及内存模型
- 2024-11-12 一文读懂Java的“栈内存”[Stack]和“堆空间”[Heap]
- 2024-11-12 JVM 内存结构(jvm内存结构及作用)
- 2024-11-12 「JVM系列」 从一到掌握JVM系列之Java虚拟机栈
- 2024-11-12 答读者问:Java 里的堆内存和栈内存是什么意思?
- 2024-11-12 Java中堆和栈的区别(java中堆和栈的区别在哪)
- 2024-11-12 一文读懂Java本地方法栈(本地方法栈jni)
你 发表评论:
欢迎- 06-15Linux中如何通过Shell脚本来控制Spring Boot的Jar包启停服务?
- 06-15推荐一款超棒的SpringCloud 脚手架项目
- 06-15IDEA将项目打包成jar包(idea打包普通java项目)
- 06-15Spring Boot3 项目 jar 包打包成 Docker 镜像全攻略
- 06-15记录Dockerfile将jar包构建成部署所需的镜像
- 06-15项目基础部署汇总八---linux下xxl-job安装
- 06-15Spring Boot Jar 包秒变 Docker 镜像实现多环境部署
- 06-15终端执行 java -jar example.jar 时报错:“没有主清单属性” 的解决
- 最近发表
-
- Linux中如何通过Shell脚本来控制Spring Boot的Jar包启停服务?
- 推荐一款超棒的SpringCloud 脚手架项目
- IDEA将项目打包成jar包(idea打包普通java项目)
- Spring Boot3 项目 jar 包打包成 Docker 镜像全攻略
- 记录Dockerfile将jar包构建成部署所需的镜像
- 项目基础部署汇总八---linux下xxl-job安装
- Spring Boot Jar 包秒变 Docker 镜像实现多环境部署
- 终端执行 java -jar example.jar 时报错:“没有主清单属性” 的解决
- 如何将本地JAR文件添加到Maven项目中
- Java 类隔离应用:多 Jar 包支持(java接口隔离原则)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)