一、虚拟机栈
1. 什么是虚拟机栈?
虚拟机栈是用于描述java方法执行的内存模型。
每个java方法在执行时,会创建一个“栈帧(stack frame)”,栈帧的结构分为“局部变量表、操作数栈、动态链接、方法出口(方法返回地址)。我们常说的“堆内存、栈内存”中的“栈内存”指的便是虚拟机栈,确切地说,指的是虚拟机栈的栈帧中的局部变量表,因为这里存放了一个方法的所有局部变量。
方法调用时,创建栈帧,并压入虚拟机栈;方法执行完毕,栈帧出栈并被销毁,如下图所示:
2. 虚拟机栈具有的一些特性:
- 虚拟机栈是线程隔离的,即每个线程都有自己独立的虚拟机栈。
- 虚拟机栈的StackOverflowError:单个线程请求的栈深度大于虚拟机允许的深度,则会抛出StackOverflowError(栈溢出错误),通常出现在无结束条件的递归方法中。虚拟机会给每个线程的虚拟机栈分配一定的内存大小(-Xss参数表示),如在栈帧中只进不出,最终导致虚拟机栈内存被耗尽。(ps:《恐怖游轮》典型的案例电影)
- 虚拟机栈的OutOfMemoryError:同样虚拟机栈也存在OOM,不同于StackOverflowError,OutOfMemoryError指的是当整个虚拟机栈内存耗尽,并且无法再申请到新的内存时抛出的异常。
二、本地方法栈
本地方法栈的功能和特点类似于虚拟机栈,均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常。
不同的是,本地方法栈服务的对象是JVM执行的native方法,而虚拟机栈服务的是JVM执行的java方法。我们常用的HotSpot虚拟机选择合并了虚拟机栈和本地方法栈。