Java虚拟机栈:
概念?答:动态内存模型
过程?答:执行方法A-创建栈帧(部变量表,操作数栈,动态链接,方法出口等信息)-入栈-出栈-结束
特点?答:线程私有 生命周期同线程所在
构成:
一、虚拟机执行引擎
虚拟机和物理机执行引擎的区别?
答:
相同点:程序代码执行能力
不同点:物理机执行引擎: --操作系统层面–执行操作系统的指令集
虚拟机的执行引擎 --自己实现 --执行虚拟机字节码指令集。
虚拟机执行方式?
答:–解释执行+编译执行
jvm执行方式: --先编译后解释:输入字节码文件-字节码解析-输出执行结果
二、运行时栈帧结构
什么是栈帧?答:
–是虚拟机进行方法调用和方法执行的数据结构,–是运行时数据区栈元素。
栈帧存储什么元素?
答:
a.局部变量表、
b.操作数栈、
c.动态链接
d.方法返回地址
执行过程:方法开始到结束,栈帧出栈到入栈。
主要空间存储是什么? 答:局部变量表和操作数栈。
空间大小什么时候确定的? 答:编译期间就已经确定 会溢出嘛? 答:超出最大深度则栈溢出异常
有效栈帧是当前栈帧 为什么? 答:位于栈顶 处于执行
a、局部变量表
用途? 答:存储方法参数和局部变量。
最小单位 是什么?答:slot 变量槽
存放什么? 答:每个Slot都应该至少能存放一个八种基本类型+reference引用类型的数据。
怎么查找? 答:通过此类型数据直接或间接地查找对象实例数据在java堆中的索引和对象所对应类在方法区中的类型信息
无初始值 须手动赋值 为什么? 答:局部变量不像类变量那样有加载过程中有准备阶段。
基础数据和对象引用在栈中. 这句话对吗?为什么?
答:不严谨,局部变量表中局部变量 会在栈中(私有) 但是成员变量和方法外对象引用是在堆中(共享)
注意:变量在局部变量表中,又不能被下一个变量作用,则在GC时,GC会引用到局部变量所指向的内存空间。从而不会被回收。
b、操作数栈
特点:先入后出
最大深度:编译时配置或者默认-XSs最大栈空间 运行时不变 超出的则抛出StackOverflowError异常
32位数据类型:栈容量为1,
64位数据类型:栈容量为2.
入栈:字节码指令写入栈
出栈:字节码指令提取栈
如:将操作数栈顶的两个int型数值出栈并相加,然后将结果入栈
java虚拟机的解释执行引擎就是基于操作数栈的执行引擎。
c、动态连接
常量池中有符号引用? 为什么?答: 符号引用本身也是常量
如何调用指令?答:以常量池指向的方法的符号引用作为参数。
什么是静态解析?答:在类加载阶段(解析阶段)或者第一次使用的时候就转化为直接引用的符号引用
什么是动态链接?答:每一次运行期间转化为直接引用的符号引用称为动态连接。
d、方法返回地址
有几种方式?答:正常完成出口和异常完成出口。
正常完成出口:执行引擎遇到一个方法返回的字节码指令,这时候执行引擎读取栈帧中的方法返回地址,将返回值传递给上层的方法调用者。
异常完成出口:在方法执行过程中遇到了异常,并且这个异常没有在方法体内得到处理,也就是在本地异常表内没有搜索到匹配的异常处理器,就会导致方法退出。
这时候执行引擎不会读取方法返回地址而直接停止执行,上层调用者不会得到任何返回值。
方法调用过程:
方法退出==当前栈帧出栈。
1. 恢复上层方法的局部变量表和操作数栈,
2. 把返回值压入调用者栈帧的操作数栈中,
3. 调整PC计数器的值以执行方法调用指令后面的一条指令。