JVM内存模型——虚拟机栈和本地方法栈

虚拟机栈是线程私有的,它的生命周期与线程一样.虚拟机栈是java方法执行时的内存模型,每个方法被执行时都会创建一个'栈帧',用于存储局部变量表、操作数栈、动态链接、方法出口等信息.每一个方法从调用到执行完成都伴随着一个'栈帧'在虚拟机栈中的入栈和出栈.

存储的内容

  1. 基础数据类型byte,boolean,char,short,int,long,float,double
  2. 对象的引用

虚拟机的特点

线程私有的,是线程隔离的,即每个线程都有自己独立的虚拟机栈。

虚拟机栈的StackOverflowError

若单个线程请求的栈深度大于虚拟机允许的深度,则会抛出StackOverflowError栈溢出错误)。

JVM会为每个线程的虚拟机栈分配一定的内存大小(-Xss参数),因此虚拟机栈能够容纳的栈帧数量是有限的,若栈帧不断进栈而不出栈,最终会导致当前线程虚拟机栈的内存空间耗尽,典型如一个无结束条件的递归函数调用,代码见下:

设置单个线程的虚拟机栈内存大小为128K,执行main方法后,抛出了StackOverflow异常

虚拟机栈的OutOfMemoryError

不同于StackOverflowError,OutOfMemoryError指的是当整个虚拟机栈内存耗尽,并且无法再申请到新的内存时抛出的异常。

JVM未提供设置整个虚拟机栈占用内存的配置参数。虚拟机栈的最大内存大致上等于“JVM进程能占用的最大内存(依赖于具体操作系统) - 最大堆内存 - 最大方法区内存 - 程序计数器内存(可以忽略不计) - JVM进程本身消耗内存”。当虚拟机栈能够使用的最大内存被耗尽后,便会抛出OutOfMemoryError,可以通过不断开启新的线程来模拟这种异常,代码如下:

设置单个线程虚拟机栈的占用内存为2m并不断生成新的线程,最终虚拟机栈无法申请到新的内存,抛出异常:

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

本地方法栈(Native Method Stack)

本地方法栈的功能和特点类似于虚拟机栈,均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常。

不同的是,本地方法栈服务的对象是JVM执行的native方法,而虚拟机栈服务的是JVM执行的java方法。如何去服务native方法?native方法使用什么语言实现?怎么组织像栈帧这种为了服务方法的数据结构?虚拟机规范并未给出强制规定,因此不同的虚拟机实可以进行自由实现,我们常用的HotSpot虚拟机选择合并了虚拟机栈和本地方法栈

发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();