JVM(Java虚拟机)内存模型是Java程序运行时的内存管理机制。JVM将内存划分为多个区域,每个区域用于存储不同类型的数据。下面详细解释JVM内存模型及其分区。
JVM内存模型
JVM内存模型主要包括以下几个部分:
- 堆内存(Heap Memory)
- 用于存储对象实例和数组。
- 是垃圾收集器管理的主要区域。
- 可以进一步划分为新生代(Young Generation)和老年代(Old Generation)。
- 新生代(Young Generation):主要用于存储新创建的对象。
- 再细分为Eden空间和两个Survivor空间(通常称为S0和S1)。
- 老年代(Old Generation):用于存储生命周期较长的对象。
- 新生代(Young Generation):主要用于存储新创建的对象。
- 方法区(Method Area)
- 存储类的结构信息,如运行时常量池、字段和方法数据、构造函数和普通方法的字节码内容等。
- 在HotSpot虚拟机中,方法区也被称为“永久代”(Permanent Generation),但在JDK 8及以后版本中,永久代被元空间(Metaspace)取代。
- 虚拟机栈(VM Stack)
- 每个线程都有一个私有的虚拟机栈,用于存储局部变量、操作数栈、动态链接、方法出口等信息。
- 每个方法在执行时都会创建一个栈帧(Stack Frame),用于存储方法的局部变量表、操作数栈等。
- 本地方法栈(Native Method Stack)
- 与虚拟机栈类似,但用于支持本地方法(用C/C++等语言编写的代码)。
- 程序计数器(Program Counter Register)
- 每个线程都有一个程序计数器,用于记录当前线程所执行的字节码指令的地址。
- 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是本地方法,这个计数器值为空(undefined)。
详细分区
-
堆内存(Heap Memory)
- 新生代(Young Generation)
- Eden空间:新创建的对象首先被分配到Eden空间。
- Survivor S0和S1:当Eden空间满时,进行Minor GC,存活的对象会被移动到其中一个Survivor空间(S0或S1)。每次GC后,两个Survivor空间的角色会互换。
- 老年代(Old Generation)
- 存储生命周期较长的对象,通常是经过多次Minor GC后仍然存活的对象。
- 新生代(Young Generation)
-
方法区(Method Area)
- 运行时常量池(Runtime Constant Pool):存储编译期生成的各种字面量和符号引用。
- 字段和方法数据:存储类的字段和方法的信息。
- 构造函数和方法的字节码内容:存储类的构造函数和方法的字节码。
-
虚拟机栈(VM Stack)
- 局部变量表:存储方法的局部变量。
- 操作数栈:用于方法执行过程中的计算。
- 动态链接:支持方法调用链的动态解析。
- 方法出口信息:记录方法返回地址等信息。
-
本地方法栈(Native Method Stack)
- 用于支持本地方法的执行,类似于虚拟机栈,但用于非Java代码。
-
程序计数器(Program Counter Register)
- 记录当前线程所执行的字节码指令的地址。