方法区、永久代(PermGen)和元空间(Metaspace)之间的关系是:
- 方法区 (Method Area) 是 JVM 规范中的一个概念。 它是一种逻辑上的区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
- 永久代 (PermGen) 和元空间 (Metaspace) 是 HotSpot 虚拟机对方法区的两种不同实现。
1. 方法区 (Method Area):
- 定义: Java 虚拟机规范中定义的一种逻辑区域,用于存储已被虚拟机加载的类信息(类名、父类、接口、字段、方法、注解等)、常量、静态变量、即时编译器编译后的代码等数据。
- 特点:
- 线程共享:所有线程共享同一个方法区。
- 逻辑区域:方法区是逻辑上的概念,具体的实现方式由虚拟机决定。
- 垃圾回收:方法区也会进行垃圾回收,主要回收废弃的常量和无用的类。
- 运行时常量池 (Runtime Constant Pool):方法区的一部分,存放编译期生成的各种字面量和符号引用,以及运行时产生的常量。
- 与类加载的关系: 类加载器加载的类信息存储在方法区中。
2. 永久代 (PermGen) (JDK 1.7 及之前):
- 定义: HotSpot 虚拟机在 JDK 1.7 及之前对方法区的实现。
- 特点:
- 使用 JVM 内存: 永久代使用 JVM 的堆内存的一部分。
- 大小固定: 永久代的大小在 JVM 启动时就固定了,可以使用
-XX:PermSize和-XX:MaxPermSize参数设置。 - 容易 OOM: 如果应用程序加载了大量的类、使用了大量的常量、或者动态生成了大量的类(例如,使用 CGLIB、Javassist 等动态代理库),就容易导致永久代溢出(
OutOfMemoryError: PermGen space)。 - Full GC: 永久代的垃圾回收和老年代的垃圾回收是绑定的,任何一个区域满了都会触发 Full GC。
- 字符串常量池: JDK 1.6 及之前, 字符串常量池位于永久代中. JDK 1.7 将字符串常量池移到了堆中.
3. 元空间 (Metaspace) (JDK 1.8 及之后):
- 定义: HotSpot 虚拟机从 JDK 1.8 开始对方法区的实现。
- 特点:
- 使用本地内存 (Native Memory): 元空间不再使用 JVM 的堆内存,而是使用本地内存(直接内存)。
- 大小动态调整: 默认情况下,元空间的大小只受本地内存大小的限制。可以通过
-XX:MetaspaceSize和-XX:MaxMetaspaceSize参数设置元空间的初始大小和最大大小。 - 减少 OOM 风险: 由于使用了本地内存,元空间不容易发生
OutOfMemoryError。但是,如果应用程序加载了大量的类,仍然可能耗尽本地内存。 - Full GC: 元空间的垃圾回收不再和老年代绑定,可以独立进行。
- 类元数据: 类元数据存储在 Metaspace 中.
- 字符串常量池: 位于堆中.
- 静态变量: 位于堆中.
关系总结:
| 概念 | 定义 | 实现 (HotSpot VM) |
|---|---|---|
| 方法区 | Java 虚拟机规范中定义的逻辑区域,用于存储类信息、常量、静态变量、即时编译器编译后的代码等。 | JDK 1.7 及之前:永久代 (PermGen);JDK 1.8 及之后:元空间 (Metaspace) |
| 永久代 | HotSpot VM 在 JDK 1.7 及之前对方法区的实现,使用 JVM 堆内存的一部分。 | |
| 元空间 | HotSpot VM 从 JDK 1.8 开始对方法区的实现,使用本地内存。 |
为什么要用元空间替换永久代?
- 避免 PermGen 溢出: 永久代的大小固定,容易发生
OutOfMemoryError: PermGen space。元空间使用本地内存,不容易溢出。 - 提高性能: 永久代的垃圾回收和老年代的垃圾回收是绑定的,效率较低。元空间的垃圾回收可以独立进行。
- 融合 JRockit 和 HotSpot: Oracle 收购 BEA 后,计划将 JRockit 和 HotSpot 融合。JRockit 没有永久代的概念。
- 支持 Java 新特性: 一些 Java 新特性(例如,Lambda 表达式、方法句柄)需要更多的元数据,永久代的大小限制可能会成为瓶颈。
- 简化 JVM 结构: 移除永久代可以简化 JVM 的实现。
总结:
方法区是 JVM 规范中的概念,永久代和元空间是 HotSpot VM 对方法区的两种实现。JDK 1.8 之后,HotSpot VM 使用元空间替代了永久代,元空间使用本地内存,减少了 OutOfMemoryError 的风险,提高了性能。
3635

被折叠的 条评论
为什么被折叠?



