JVM程序计数器,虚拟机栈,本地方法栈
程序计数器
它记录了程序执行字节码的行号和指令,字节码解释器的工作就是改变程序计数器的值,切换下一条需要执行的指令(分支,循环,跳转,异常等)。java虚拟机是多线程通过轮流切换CPU时间片的方式实现,在同一时间内,CPU只会执行一个线程中的一个指令,为了每次切换回来都能到正确的执行位置,每个线程都会有一个独立的线程计数器,每个计数器不会相互影响,并且是线程私有的。由于不是开发者操作,所以是不会产生异常的。
虚拟机栈
虚拟机栈也是线程私有的,它的声明周期与线程一样(和线程同生死)。如果线程请求栈的深度大于虚拟机所允许的深度则会报错
StackOverFlow
的错误。如果虚拟机可以动态扩展,如果扩展后无法获得到内存,就会报错OutOfMemoryError
。java虚拟机栈描述的是Java方法执行的内存模型,每个方法执行的同时都会创建一个栈帧,对于我们来说主要关注栈内存,也是方法内的局部变量。
栈帧
栈帧虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区虚拟机栈的栈元素。栈帧存储了方法的局部变量表,操作数栈,动态链接和方法返回地址信息。在程序编译期,栈帧需要多大的局部变量表内存,多深的操作数栈已经确定。在活动线程中,栈顶的栈帧才是有效的,与这个栈帧关联的方式是当前方法,执行引擎运行的所有字节码指令都只会作用于当前栈帧。
本地方法栈
本地方法栈和虚拟机栈发挥的作用基本一样。区别是:本地方法栈执行的是Native方法服务,而虚拟机栈执行的是java方法。在HotSpot vm中本地方法栈和虚拟机栈合二为一。
注意:
当一个线程调用本地方法时,就会进入了一个不受java虚拟机限制的世界,它和虚拟机有着同样的权限。本地方法可以通过本地接口访问虚拟机运行时数据区。它可以直接使用本地处理器的寄存器。并不是所有的JVM都支持本地方法。如果JVM产品不打算支持Native方法,也可以不用实现本地方法栈。