转: http://www.cnblogs.com/myna/p/7567208.html
java 虚拟机运行时数据区, 具体分为如下几个区域
程序计数器(Program Counter Register)
程序计数器是一块很小的内存区域, 存储了下一条需要执行的字节码指令的地址, 此处的地址可以是一个本地指针, 也可以是在方法区中相对应于该方法起始指令的偏移量. 每个线程都有独立的程序计数器 (PCR), 在线程启动时会创建, 多线程切换时可以恢复每一个线程的当前执行位置, 所以线程之间不会相互影响. 当执行 Java 方法时, 这里存储的执行的字节码指令的地址(当前被执行的 JVM 地址), 如果执行的是本地(Native) 方法, 这里的值是 Undefined. 程序计数器区域是唯一一个 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域.
虚拟机栈(VM Stack)
虚拟机栈是线程私有的, 每创建一个线程, 虚拟机就会为这个线程创建一个虚拟机栈, 虚拟机栈表示 Java 方法执行的内存模型, 每调用一个方法就会为每个方法生成一个栈帧(Stack Frame), 用来存储局部变量表, 操作数栈, 动态链接, 方法出口等信息. 每个方法被调用和完成的过程, 都对应一个栈帧从虚拟机栈上入栈和出栈的过程. 虚拟机栈的生命周期和线程是相同的. 如果请求的栈深度过大, 虚拟机可能会抛出 StackOverflowError 异常, 如果虚拟机的实现中允许虚拟机栈动态扩展, 当内存不足以扩展栈的时候, 会抛出 OutOfMemoryError 异常.
本地方法栈(Native Method Stack)
功能和虚拟机栈类似, 执行本地方法时使用的. 存储线程调用本地方法时, 本地方法的局部变量表, 操作数栈等信息. 本地方法栈区域也会抛出 StackOverflowError 和 OutOfMemoryError 异常.
堆(Heap)
一个 Java 虚拟机实例中存在一个堆空间, 在虚拟机启动时创建, 被所有线程共享. 用于存放对象与数组实例的地方. 是 JAVA 虚拟机所管理的内存中最大的一块. 是垃圾收集器管理的主要区域.(还可能有方法区) 堆中 OutOfMemoryError 异常出现的比较多, 如 JVM 创建的对象太多导致内存占满的情况.
方法区(Method Area)
用于存储已被虚拟机加载的类型信息, 常量, 静态变量, 即时编译后的代码等信息. 方法区是线程间共享的, 当两个线程同时需要加载一个类型时, 只有一个类会请求 ClassLoader 加载, 另一个线程会等待. 当方法区无法满足内存分配需求时, 将抛出 OutOfMemoryError 异常. jdk8 中, 移除了方法区, 转而用 Metaspace(元数据区)替代
来源: http://www.bubuko.com/infodetail-2645279.html