JVM规范将运行时数据区分为6个部分。PC寄存器,栈,本地方法栈,堆,方法区。其中PC寄存器,栈,本地方法栈是线程私有的,后二者是线程共享的。数组
PC寄存器(程序计数器),它用来记录当前线程运行的下一条字节码指令的地址,或者说是是保存当前线程指令执行的指针。(没有定义OutOfMemoryError)线程
JVM栈,每一个方法执行的时候同时建立一个栈帧,存储局部变量表,操做数栈,动态连接,方法出口等信息。一个方法运行的过程就是入栈道出栈的过程。这个区域定义了两种异常:若是请求的栈深度大于JVM所容许的深度,将抛出StackOverflowError。若是栈扩展时没有足够的内存,将抛出OutOfMemoryError。指针
本地方法栈,做用于JVM栈很是类似,只不过它执行的是本地Native方法,也定义了和JVM相同的异常。对象
Java堆,JVM所管理的最大的一块内存,全部线程共享。几乎全部的对象和数组都在堆上分配,也是GC管理的主要区域。经过-Xmx,-Xms参数来设置。若是堆中没有可分配的内存,将抛出OutOfMemoryError.内存
方法区,与堆同样是全部线程共享的区域,用于保存JVM加载的CLass信息、常量、静态变量等数据。它属于堆的一部分,在HotSpot虚拟机上也称为永久带。虚拟机
常量池,这属于方法区的一部分,主要用来存放编译期生成的各类字面量与符号引用。运行时如String.intern()也能加入新的常量池。没法申请内存时也将抛出OutOfMemoryError.编译
直接内存,不是JVM运行时数据区的内存,也不是JVM规范定义的内存,例如NIO的DirectByteBuffer就分配在本机直接内存,也会出现OutOfMemoryError的状况变量