这里翻译自:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html 第2.5节运行期数据区域划分.
JVM规范定义了程序在运行期间不同数据区域的划分。其中部分数据是在JVM启动时创建,同时在JVM结束时消失。另一些则与线程相关,在线程被创建时被创建,线程结束时这部分数据被删除。
总共的区域划分为 PC寄存器,线程执行栈,数据堆,方法区,常量池,本地执行栈,共6个区域。
A PC寄存器
在同一时刻,在JVM内部有多个线程在同时执行。在某一时刻,线程就会取出一条指令进行执行,那么PC寄存器就表示当前线程正在执行哪一条指令,即正在执行指令的一个引用指针,以方便进行定位和执行下一条指令。即寄存器会同时记录每个线程的执行点。如果当前线程正在执行native方法时,寄存器的值是未定义的。
B 线程执行栈
线程执行栈即表示每一个线程在执行不同的方法所创建的按方法区分的帧。就比如在调用ex.printStackTrace时,每一个调用方法就表示一个方法帧。在每个方法帧上,存储着在当前执行点上存储的一些临时变量以及下个方法返回的数据值。在具体执行时,当调用一个新方法时,就会创建一个新的执行帧,同时push到当前的执行栈中;当方法返回时,就会把当前的执行帧从执行栈中pop掉。
在具体实现时,每个执行栈的内存并没有要求一定是连续的。
在某些情况下,特别是在递归调用中,经常会报StackOverflowError的错误,就是因为创建的执行帧太多,而每个执行帧会占用一定的内存。当总执行栈超过设定值时,就会发生这个异常。比如,在Oracle JVM上,可以通过-Xss来指定每个执行栈的最大内存。