概述
本文将介绍Java虚拟机(JVM)内存的各个区域,了解虚拟机是怎样使用内存的。
运行时数据区域
根据虚拟机规范,虚拟机所管理的内存将会包括以下几个运行时数据区域,如下图所示。
- 线程独占:每个线程都会有它独立的空间,随线程生命周期而创建和销毁
- 线程共享:所有线程能访问这块内存数据,随虚拟机或者GC而创建和销毁
方法区
方法区用于存储已被虚拟机加载的类信息、常量、静态变量、编译后的代码等数据。方法区只是虚拟机规范重的一个逻辑区划,具体的实现不受规范约束。如:
- HotSpot在java7中将方法区放在永久代(使用永久代实现方法区),通过GC机制进行管理
- HotSpot在java7中将方法去存储在元数据空间,通过GC机制进行管理
堆内存
Java堆由虚拟机启动时创建,唯一的目的就是存放对象实例。也因为Java堆是垃圾收集器管理的主要区域,因此很多时候也称为“GC堆”。由于收集器采用分代收集算法,堆内存还可以细分为:老年代、新生代(Eden、From Survivor、To Survivor)
虚拟机栈
Java虚拟机栈是线程私有的,每一个线程都在空间有一个私有的空间,它的生命周期和线程相同。虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧。栈帧内容包含:局部变量表、操作数栈、动态连接、方法放回地址、附加信息等。
本地方法栈
本地方法栈和虚拟机栈功能类似,虚拟机栈是为虚拟机执行Java方法而准备的,本地方法栈是为虚拟机使用Native本地方法而准备的。
程序计数器
为了线程线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,线程间互不影响。程序计数器可以看作是当前线程所执行的字节码的行号指示器,记录当前线程执行字节码的位置,存储的是字节码指令地址,如果是Native方法,这个计数器值为空。