虚拟机二:自动内存管理机制 之 运行时数据区域

一、运行时数据区域

虚拟机二:自动内存管理机制 之 运行时数据区域
图片引用 周志明<深入理解Java虚拟机>

 1.1、程序计数器

.class文件也叫字节码文件,是虚拟机解释运行的目标文件。程序计数器就是当前线程所执行的字节码的行号指示器,属于线程私有的一块小内存。当多线程来回切换时,使用程序计数器能正确的恢复到之前执行的位置。

如果正在执行Java方法,则程序计数器记录的是正在执行的字节码指令的地址;如果是native方法,则记录空(Undefined);此区域是唯一一块不会OutOfMemoryError(OOM的内存区域

1.2、Java栈

Java栈也是线程私有的,与线程生命周期相同,有时候也可以称为 '方法栈'。

每个方法被执行时都会生成一个栈帧,用来保存局部变量、操作数栈等。

方法调用时会产生两种异常,当调用深度大于Java虚拟机设定的阈值时会抛出*Error;当方法执行时,内存不够分配时,会抛出OutOfMemoryError异常。

Java栈分为Java虚拟机栈与本地方法栈:

  • Java虚拟机栈:服务于Java方法
  • 本地方法栈:服务于本地方法。native 方法

1.3、Java堆(Java Heap)

Java堆属于Java虚拟机所管理的内存最大、最核心的内存区域;此区域为所有线程共享,也是垃圾回收器最主要的工作对象。

几乎所有的对象实例都在堆上分配内存,也有很少的对象实例会在栈上分配。

从内存回收的角度看,堆又分为新生代与老年代;再细致可分为Eden区、From Survivor区、To Survivor区等

从内存分配的角度看,Java堆可分为多个本地线程分配缓冲去(Thread Local Allocation Buffer,TLAB)。

1.4、本地方法区(Non-Heap)

  • 存储类信息、常量、静态变量、即时编译后的代码等
  • 线程共享
  • 也被称为"永久代"

1.5、运行时常量池

属于本地方法区的一部分

1.6、直接内存

并不属于Java虚拟机运行时的数据区域的一部分,但是也会频繁的使用,也会导致OOM。例如java的NIO