虚拟机栈
概述
出现的背景
栈是运行时的单位,堆是存储的单位
基本内容
1、一个线程对应一个Java虚拟机栈
2、保存的是一个个的栈帧,一个栈帧对应一个JAVA方法
特点
优点
不需要GC, 因为入栈出栈的存在,但是存在OOM
面试问题
问题:开发种遇到的异常有哪些
设置栈内存大小
栈的存储单位
栈中存储了什么
当前在执行方法4 栈帧4 在栈顶
栈的运行原理
栈帧的内部结构
局部变量表(本地变量表)
jclasslib插件 看字节码指令和代码行一一对应,看局部变量表的数字数组的大小,每个变量的作用域(声明之后的行号)。
slot – 局部变量表的基本单位(槽)
静态方法里为什么不能使用this
因为静态方法里的局部变量表里没有this,普通方法indedx为0的slot是this
查看局部变量表 用jclasslib插件
slot重复利用
局部变量必须要显式赋值
操作数栈
栈:可以使用数组或链表来实现
什么是操作数栈
jclasslib查看
代码追踪
栈顶缓存技术
动态链接
原理 :指向 运行时常量池 的 方法引用
一个地址:保存在运行时常量池方法的引用地址
字节码文件中常量池:constant Pool #1 表示 符号引用
动态链接的作用就是为了讲这些符号引用转换为调用方法的直接引用
为什么需要常量池 ?
常量池的作用,就是为了提供一些符号和常量,便于指令识别。
方法返回地址 (PC寄存器存储的值)
原理
一些附加信息
方法的调用
什么是方法的调用
静态链接 动态链接
早期绑定 晚期绑定
静态链接对应早期绑定,动态链接对应晚期绑定。 java面向对象的多态就是动态链接。继承或实现接口重写的方法都属于动态链接,晚期绑定。
非虚方法 对应静态链接或早期绑定
方法重写的本质
虚方法表
虚拟机栈常见面试问题
1、举例栈溢出的情况 (StackOverFlowError)
. 通过 -Xss 调整栈的大小 ;OOM
2、调整栈大小,就能保证不出现溢出吗?不能 , 只能保证多用几次,不能保证不出现溢出
3、分配的栈内存越大越好吗?不是,栈内存大了 线程数会变少。
4、垃圾回收会涉及到虚拟机栈吗?不会的 会存在error不存在GC
5、方法中定义的局部变量是否线程安全?具体问题具体分析
method1中 s1是线程安全的。在方法内部使用完就死亡了。
method2中 sBuilder 是从外部传进来的,线程不安全
method3 带有StringBuilder的返回,可能会被其他线程修改,所以线程不安全。
method4 中的 s1 在内部死亡了。返回的String 值可能存在线程不安全问题,但是s1是线程安全的。在方法内部使用完就死亡了。