虚拟机栈
虚拟机栈是用于描述java方法执行的内存模型。
每个java方法在执行时,会创建一个“栈帧”,栈帧的结构分为“局部变量表、操作数栈、动态链接、方法出口”几个部分。通常说的“堆内存、栈内存”中的栈内存指的就是虚拟机栈,确切的说,指的是虚拟机栈的栈帧中的局部变量表,因为这里存放了一个方法的所有局部变量。
虚拟机栈的特点
线程私有,每个线程都有自己独立的虚拟机栈。
虚拟机栈的StackOverflowError
若单个线程请求的栈深度大于虚拟机允许的深度,则会抛出StackOverflowError(栈溢出错误)
JVM会为每个线程的虚拟机栈分配一定的内存大小(-Xss参数),因此虚拟机栈能够容纳的栈帧数量是有限的,若栈帧不断进栈而不出栈,最终会导致当前线程虚拟机栈的内存空间耗尽。比如一个无结束条件的递归函数调用。
虚拟机栈的OutOfMemoryError
不同于StackOverflowError,OutOfMemoryError指的是当整个虚拟机栈内存耗尽,并且无法再申请到新的内存时抛出的异常。
JVM未提供设置整个虚拟机栈占用内存的配置参数。虚拟机栈的最大内存大致上等于“JVM进程能占用的最大内存”。当虚拟机栈能够使用最大内存被耗尽后,便会抛出OutOfMemoryError,可以通过不断开启新的线程来模拟这种异常。
本地方法栈
本地方法栈的功能和特点类似于虚拟机栈,均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常。
不同的是,本地方法栈服务的对象是JVM执行的native方法,而虚拟机栈服务的是JVM执行的java方法。我们常用的HotSpot虚拟机选择合并了虚拟机栈和本地方法栈。