1、虚拟机栈结构示意图:
2、栈帧结构示意图:
1、“堆和栈”中存放局部变量的栈(和存放对象的堆),但是不仅仅存放局部变量,存放局部变量的只是里面的变量表部分。
2、栈针是方法执行产生的内存,每一个方法会创建一个栈帧,用于存储局部变量表、操作栈、动态链接、方法出口等信息。
- 局部变量表存放了编译器可知基本数据类型(boolean、byte、char、short、int、float、long、double)和引用所指向的地址(这个地址可能是对象的地址,也可能是对象地址所在的地址(句柄),也可能是指令的地址)
注意:string类型的值没有存放在这里。这里存放的只是指向堆中或者方法区常量池的地址。
- 局部变量表的内存大小,在编译期就能确定,在方法执行时,内存分配后,就不会改变。
3、每一个方法从被调用到执行完成,就是一个栈帧在虚拟机栈中从入栈到出栈的过程。
4、虚拟机栈也是线程独立的。也就是每个线程有自己的栈帧。
5、虚拟机栈可能出现的两种异常:栈溢出和内存溢出。
- 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常(如:将一个函数反复递归自己,最终会出现这种异常)。
- 如果JVM栈可以动态扩展(大部分JVM是可以的),当扩展时无法申请到足够内存则抛出OutOfMemoryError异常。
3、本地方法栈
(1)本地方法栈与虚拟机栈所发挥的作用很相似,他们的区别在于虚拟机栈为执行Java代码方法服务,而本地方法栈是为Native方法服务(也就第3方的:c/c++等)。
(2)和JVM栈一样,这个区域也会抛出StackOverflowError和OutOfMemoryError异常。
(3)甚至有的虚拟机(譬如Sun HotSpot虚拟机)直接就把本地方法栈和虚拟机栈合二为一。