博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JVM中的Stack和Frame
阅读量:6402 次
发布时间:2019-06-23

本文共 1806 字,大约阅读时间需要 6 分钟。

JVM执行Java程序时需要装载各种数据,比如类型信息(Class)、类型实例(Instance)、常量数据(Constant)、本地变量等。不同的数据存放在不同的内存区中,这些数据内存区称作“运行时数据区(Runtime Data Area)”。运行时数据区有这样几个重要区:JVM Stack(简称Stack或者虚拟机栈、线程栈、栈等),Frame(又称StackFrame/栈帧、方法栈等),Heap(堆/GC堆,即垃圾收集的对象所在区)。下面简单介绍一下Stack和Frame,对于Heap,。

概览

单个线程内共享的区:PC Register/JVM Stack/Native Method Stack。

所有线程共享的区:Heap/Method Area/Runtime Constant Pool。

上图:运行时数据区。重点是每个线程拥有的PCRegister/Stack以及线程共享的Heap以及常量池(ConstantPool)

 

 

上图:线程栈(VM Statck/Stack)包含的栈帧(Frame)。重点是栈帧和它的结构,操作栈(OperandStack)以及常量池引用。

Stack

结构:{JVM Stack [Frame][Frame][Frame]... }。

JVM Stack在每个线程被创建时被创建,用来存放一组栈帧(StackFrame/Frame)。
JVM Statck的大小可以是固定的,也可以是动态扩展的。如果线程需要一个比固定大小大的Stack,会发生StackOverflowError;如果动态扩展Stack时没有足够的内存或者系统没有足够的内存为新线程创建Stack,发生OutOfMemoryError。

Frame

结构:{Frame [ReturnValue] [LocalVariables[][][][]...] [OperandStack [][][]...] [ConstPoolRef] }

每次方法调用均会创建一个对应的Frame,方法执行完毕或者异常终止,Frame被销毁。一个方法A调用另一个方法B时,A的frame停止,新的frame被创建赋予B,执行完毕后,把计算结果传递给A,A继续执行。

 

局部变量表

局部变量表的大小在编译期就被确定。基元类型数据以及引用和返回地址(returnAddress)占用一个局部变量大小,long/double需要两个。

Java代码“int a=0;int b=1;int c=2;”对应的局部变量表如下:

LocalVariableTable:Start Length Slot Name Signature2 12 0 a I4 10 1 b I6 8 2 c I

Start: 变量偏移量。

Length: 作用域范围长度。[Start,Start+Length)就是该变量的作用域。
Slot: 一个Slot能存储32bit的数据类型、引用、返回地址,long/dobule需要两个Slot。

操作栈(OperandStack)
Frame被创建时,操作栈是空的。操作栈的每个项可以存放JVM的各种类型数据,包括long/double。
操作栈有个栈深,long/double贡献两个栈深。
操作栈调用其它有返回结果的方法时,会把结果push到栈上。

Java代码:

int a=1;int b=2;int c=a+b;

对应的指令:

0: iconst_1 // push 1到操作栈。大于5的int值会用到 bipush  指令。1: istore_0 // pop 顶元素,存储到index=0的本地变量。2: iconst_2 // push 2 到操作栈3: istore_1 // pop栈顶元素,存储到index=1的本地变量。4: iload_0  // 把index=0的本地变量加载到栈顶5: iload_1  // 把index=1的本地变量加载到栈顶6: iadd     // 把栈顶两个数pop出来相加,并把结果存放到栈顶7: istore_2 // 结果存储到index=2的本地变量

 

Reference

1.   
2.   
3. 《深入理解Java虚拟机》

转载于:https://www.cnblogs.com/caca/p/jvm_stack_frame.html

你可能感兴趣的文章
ext不能选中复制属性_如何实现Extjs的grid单元格只让选择(即可以复制单元格内容)但是不让修改?...
查看>>
python中print的作用*8、不能+8_在 Python 3.x 中语句 print(*[1,2,3]) 不能正确执行。 (1.0分)_学小易找答案...
查看>>
python 生成html代码_使用Python Markdown 生成 html
查看>>
axure如何导出原件_Axure 教程:轻松导出图标字体所有图标
查看>>
laravel input值必须不等于0_框架不提供,动手造一个:Laravel表单验证自定义用法...
查看>>
cad填充图案乱理石_太快了吧!原来大神是这样用CAD图案填充的
查看>>
activator.createinstance 需要垃圾回收么_在垃圾回收器中有哪几种判断是否需要被回收的方法...
查看>>
rocketmq 消息指定_RocketMQ入坑系列(一)角色介绍及基本使用
查看>>
redis zset转set 反序列化失败_掌握好Redis的数据类型,面试心里有底了
查看>>
p图软件pⅰc_娱乐圈最塑料的夫妻,P图永远只P自己,太精彩了吧!
查看>>
jenkins 手动执行_Jenkins 入门
查看>>
怎么判断冠词用a还是an_葡语干货 | 葡萄牙语冠词用法整理大全
查看>>
js传参不是数字_JS的Reflect学习和应用
查看>>
三个不等_数学一轮复习05,从函数观点看方程与不等式,记住口诀与联系
查看>>
右键新建文件夹_Macos电脑鼠标右键木有新建文档咋办,有办法,莫捉急
查看>>
卡尺测量的最小范围_汽车维修工具-测量用具
查看>>
网优5g前景_5G网络优化师前景怎么样?
查看>>
竞态条件的赋值_[译] part25: golang Mutex互斥锁
查看>>
delmatch oracle_完美完全卸载(清除)oracle数据库的方式(方法)
查看>>
pyqt 滚动条 美化_Pyqt5 关于流式布局和滚动条的综合使用示例代码
查看>>