求2023版OpenJDK JVM内存布局完整概述与结构示意图
OpenJDK(2023年版)JVM内存布局全面概述
以下基于OpenJDK 17/21(2023年主流LTS版本)的HotSpot虚拟机实现,明确各核心内存区域的归属与嵌套关系:
一、Heap(堆)- 线程共享区域
堆是JVM管理的最大内存区域,用于存储所有对象实例,由垃圾回收器自动管理:
- Young Generation(年轻代)
- Eden Space:新创建的对象优先分配至此区域
- Survivor Spaces(S0、S1):垃圾回收后存活的对象会被转移到这里,两个区域始终有一个为空
- Old Generation(老年代/ Tenured Generation):年轻代中多次回收仍存活的对象会晋升至此,存储长期存活的对象
- String Pool(字符串常量池):JDK 7及以后从永久代移至堆中,存储字符串字面量的引用(实际字符串对象根据存活时长分布在年轻代或老年代)
二、Non-Heap(非堆)- 线程共享区域
非堆区域存储JVM运行所需的非对象数据,不受垃圾回收器直接管理:
- Metaspace(元空间):替代JDK 8之前的PermGen(永久代),是Method Area(方法区)的物理实现(方法区是JVM规范中的逻辑概念)
- Runtime Constant Pool(运行时常量池):每个类/接口加载后都会生成对应的运行时常量池,存储编译期生成的常量、符号引用、动态生成的常量等,属于Metaspace的一部分
- 类元数据:存储类的结构信息、字段定义、方法定义、注解等
- Code Cache(代码缓存):独立于Metaspace的非堆区域,存储JIT(即时编译)生成的本地机器码、解释器生成的代码,以及JNI(Java本地接口)代码
三、Thread Stack(线程栈)- 线程私有区域
每个线程启动时都会创建一个独立的栈,线程销毁时栈也随之释放:
- 栈由多个栈帧组成,每个栈帧对应一次方法调用,包含局部变量表、操作数栈、动态链接、方法返回地址等信息
- 完全独立于堆和非堆区域,内存大小可通过
-Xss参数配置
内存区域嵌套关系示意图
graph TD A[JVM总内存] --> B[Heap(线程共享)] A --> C[Non-Heap(线程共享)] A --> D[Thread Stack(线程私有,每个线程一个)] B --> B1[Young Generation] B1 --> B1a[Eden Space] B1 --> B1b[Survivor S0] B1 --> B1c[Survivor S1] B --> B2[Old Generation] B --> B3[String Pool] C --> C1[Metaspace] C1 --> C1a[Runtime Constant Pool(类/接口级)] C1 --> C1b[类元数据] C --> C2[Code Cache]
关键概念澄清
- Constants Pool(常量池):分为两类,编译期常量池存储在
.class文件中,类加载后会被加载到Metaspace的运行时常量池;不要与String Pool混淆,String Pool仅存储字符串字面量的引用 - Metaspace默认使用本地系统内存(而非JVM堆内存),可通过
-XX:MetaspaceSize(初始阈值)和-XX:MaxMetaspaceSize(最大上限)配置内存范围 - Method Area是JVM规范定义的逻辑区域,OpenJDK中没有单独的物理区域,完全由Metaspace实现
信息来源:OpenJDK 17官方《Java Virtual Machine Specification》第2.5节、HotSpot虚拟机实现文档
内容的提问来源于stack exchange,提问作者fascynacja
相关产品推荐
相关产品推荐

