当前位置:网站首页>jvm 二之 栈帧内部结构
jvm 二之 栈帧内部结构
2022-08-02 06:29:00 【兮家小二】
栈帧内部结构
1、内存结构
在每一个方法 栈帧中都会有自己独立的,其中包括
- 1、局部变量表 (存放当前方法对应的局部变量);
- 2、操作数栈 (或表达式栈);
- 3、动态连接 (或指向运行时常量池的方法引用)
- 4、方法出口 (或方法正常退出或者异常退出的定义)
栈帧包含方法的所有信息
使用 javap -v Demo03.class
查看转成汇编后的源码
2、idea 分析插件
打开idea 中的settings > plugins 搜索 jclasslib
插件
重启后点击 view > 选择 show bytecode with jclasslib
查看分析
一、局部变量表
局部变量表中的变量只在 当前方法
调用中有效。
在方法执行时,虚拟机通过使用局部变量表完成参数值到参数变量列表的传递过程。
当方法调用结束后,随着方法栈帧的销毁,局部变量表也会随之销毁。
每一个方法都有一个局部变量表
1.1、Slot(变量槽–index)
public static void main(String[] args) {
String str = "mayikt";
int j = 20;
double d = 66.66;
boolean b = true;
}
如下: JVM会为局部变量表中每一个变量分配变量槽
- args 参数: 在 局部变量表中 slot 索引 0 的位置
- str 参数: 在 局部变量表中 slot 索引 1 的位置
- j 参数: 在 局部变量表中 slot 索引 2 的位置
- d 参数: 在 局部变量表中 slot 索引 3 的位置 (double 会占用两个槽位)
- b 参数: 在 局部变量表中 slot 索引 5 的位置
局部变量表最基本的存储单元就是变量槽。
- 32位以内的类型只占用一个slot (包括returnAddress类型),
- 64位的类型(long和double)占用两个slot。
- short,byte,boolean 等数据也占用一个变量槽,因为jvm会在存储时将上述变量转为int类型(变量槽是最基本存储单元,无法分割,只能整个使用)。
1.2、变量槽的复用
public static void mayikt002() {
int a = 0;
{
int b=30;
System.out.println("mayikt");
}
int c = 0;
}
此处原因就是JVM对变量槽有一个复用性为
- 变量b 使用了变量槽 1, 超出其作用域后不再生效,
- 变量c 发现变量槽 1 其作用域后超出, 直接占据了 b 的位置
1.3、变量槽中的 this
如果当前的方法是实例方法
或者是构造方法
则jvm默认会在局部变量表中创建 一个当前对象 this
, 存入在我们当前方法对应的局部表第0个位置
这样我们就可以在实例方法中 使用 this,静态方法不会。
public void mayikt() {
int j = 20;
}
变量槽中默认存在 this 变量
二、操作数栈
mian 调用 a, a 调用 b ,b 调用c , c调用 d, 方法会压入到栈空间中
而操作数栈是值变量的操作进行的压栈操作,从而可以执行相关 加减乘除 操作
2.1、基础操作 指令解析
当前代码
public int compute() {
int a = 10;
int b = 20;
int c = (a + b) * 10;
return c;
}
转汇编后的代码 , javap -v xxxx.class
0: bipush 10 // 将一个8位带符号整数压入栈
2: istore_1 // 变量槽 1 a 存入 10
3: bipush 20 // 将一个8位带符号整数压入栈
5: istore_2 // 变量槽 2 b 存入 20
6: iload_1 // 获取槽1 变量a=10;
7: iload_2 // 获取槽2 变量a=20;
8: iadd // i执行int类型的加法 10+20=30
9: bipush 10 // 将一个8位带符号整数压入栈 10
11: imul // imul 执行int类型的乘法 30*10=300
12: istore_3 // 变量槽3 c存入计算结果 300
13: iload_3 // 获取槽3 变量c=300;
14: ireturn // 方法返回最后读取的变量槽数据
2.2、i++ 和 ++i 解析
i++
执行+1 前压入的栈数据, 栈顶数据是 0
++i
执行+1 后压入的栈数据, 栈顶数据是 1
2.3、栈溢出
StackOverflowError(栈溢出)
StackOverflowError代表的是,当栈深度超过虚拟机分配给线程的栈大小时就会出现此error
默认是有最大深度的, 常出现在递归调用中
2.4、方法出口
方法返回地址
2.5、动态链接
在操作数栈中找到被调用的子方法就是动态链接
动态链接: 每个栈帧都保存了 一个可以指向当前方法所在类的 运行时常量池,
目的是: 当前方法中如果需要调用其他方法的时候, 能够从运行时常量池中找到对应的符号引用, 然后将符号引用转换为直接引用,然后就能直接调用对应方法, 这就是动态链接
三、常量池
什么是常量池(Constant Pool)
java经过编译后生成的.class文件,是Class文件的资源仓库。
常量池分类:
- 运行时常量池 ,jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在元空间中,我们常说的常量池,就是指方法区中的运行时常量池
- 静态常量池 class文件的关键信息,
类和接口的全限定名
,字段的名称和描述符
,方法的名称和描述符
,以及被 final 修饰的常量值等,如数量值
字符串值
以及字面量(Literal)和符号引用(Symbolic References) ,如:类引用
字段引用
方法引用
- 静态常量池 class文件的关键信息,
- 字符串常量池 顾名思义,存放字符串, 如:
Strng
,StringBuffer
,StringBuffer
等,jdk7 之前 方法区
,JDK7 存放在堆中
,JDK 8
方法区改 元空间字符串常量池
还是存放在我们堆中
。
- 字符串常量池 顾名思义,存放字符串, 如:
元空间就是之前的方法区
边栏推荐
- typescript 'props' is declared but its value is never read solution
- odoo field 设置匿名函数domain
- C# FileInfo类
- MQ带来的一些问题、及解决方案
- 【npm install 报错问题合集】- npm ERR! code ENOTEMPTY npm ERR! syscall rmdir
- 笔记本开机黑屏提示:ERROR 0199:System Security-Security password retry count exceeded
- MySQL high-level --- storage engine, index, lock
- (Part of it is not understood, and the notes are not completed) [Graph Theory] Difference Constraints
- Unity Shader学习(七)纹理图像的简单使用
- 看图就懂|衡量业务增长健康的销售指标如何选择
猜你喜欢
2022.07.31(LC_6132_使数组中所有元素都等于零)
PMP新考纲通关秘籍,告别抓瞎
MQ带来的一些问题、及解决方案
每周推荐短视频:为什么产品开发需要数字化?如何做到数字化?
awk语法-01-基础语法(命令、选项、内部变量)
File upload vulnerability (2)
CAT1 4G+Ethernet development board Tencent cloud mobile phone WeChat applet display temperature and delivery control
How does abaqus quickly import the assembly of other cae files?
System.Security.SecurityException: 未找到源,但未能搜索某些或全部事件日志。不可 访问的日志: Security
实例028:递归求等差数列
随机推荐
Swagger的简单介绍,集成,以及如何在生产环境中关闭swagger,在测试和开发环境中自动打开
DNS resolution process
交换--STP协议
(部分不懂,笔记整理未完成)【图论】差分约束
Leetcode周赛304
享年94岁,图灵奖得主、计算复杂性理论先驱Juris Hartmanis逝世
love
振兴农村循环经济 和数链串起农业“生态链”
PHP Warning: putenv() has been disabled for security reasons in phar
HCIP 第三天实验
August 2022 plan, focusing on ue4 video tutorials
Py's mlxtend: a detailed guide to the introduction, installation, and usage of the mlxtend library
论文《Deep Multifaceted Transformers for Multi-objective Ranking in Large-Scale E-commerce Recommender》
Resolving C# non-static field, method or property "islandnum.Program.getIslandCount(int[][], int, int)" requires an object reference
2022夏暑假每日一题(六)
Connection reset by peer problem analysis
SQL执行顺序
Nodejs installation tutorial
2022.07.31(LC_6133_分组的最大数量)
解决Pytorch模型在Gunicorn部署无法运行或者超时问题