深入理解Java虚拟机-Java内存区域

1.Java内存模型

Java虚拟机的逻辑模型如下图:

深入理解Java虚拟机-Java内存区域

从图中我们可以知道,Java内存模型可以分为5块,其中线程共享的有两个区域,分别是堆和方法区,线程独占的有三个区域,分别是虚拟机栈,本地方法栈和程序计数器。

(1)程序计数器

  • 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器;
  • 程序计数器处于线程独占区;
  • 如果线程执行的是Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址。如果正在执行的是native方法,这个计数器的值为undefined;
  • 此区域是唯一一个在Java虚拟机规范中没有规定任何OutofMemeoryError情况的区域。

(2)虚拟机栈

  • 虚拟机栈描述的是Java方法执行的动态内存模型;
  • 栈帧:每个方法执行,都会创建一个栈帧,伴随着方法从创建到执行完成。用于存储局部变量表,操作数栈,动态链接,方法出口;
  • 局部变量表:存放编译期可知的各种基本数据类型,引用类型,返回地址类型。局部变量表的内存空间在编译期完成分配,当进入一个方法时,这个方法需要在帧分配多少内存是固定的,在方法运行期间是不会改变局部变量表的大小;
  • 异常:*Error OutOfMemoryError。

(3)本地方法栈

  • 为虚拟机执行native方法服务;

(4)堆内存

  • 存放对象实例;
  • 垃圾回收器管理的主要区域;
  • 分为新生代,老年代;
  • 会抛出 OutofMemoryError;
  • 最小堆,最大堆虚拟机参数 -Xms -Xmx。

(5)方法区

  • 存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,类信息包括类的版本,字段,方法和接口;
  • 方法区和永久代;
  • 垃圾回收在方法区的行为,回收常量;
  • 异常定义:OutOfMemoryError。

(6)特殊的内存区域

  • 运行时常量池;
  • 直接内存 nio中分配DirectByteBuffer,即堆外内存。