JVM 的内存区域是如何划分的?
JVM 的内存区域划分
JVM 在运行时会将内存划分为多个区域,用于管理程序运行时的不同类型数据。以下是 JVM 内存的主要划分:
1. 方法区(Method Area)
-
定义:
方法区是运行时数据区的一部分,用于存储类的元信息(元数据)以及与类相关的常量。 -
存储内容:
- 类的元信息(类名、访问修饰符、方法描述等)。
- 静态变量。
- 运行时常量池(编译时生成的常量,如字符串常量)。
- 方法的字节码。
-
特点:
- 是线程共享的区域。
- JDK 8 之前称为永久代(PermGen),JDK 8 之后改为元空间(Metaspace),并从堆内存移到本地内存。
2. 堆区(Heap Area)
-
定义:
堆是 JVM 中最大的内存区域,主要用于存储对象实例和数组。 -
存储内容:
- 所有的对象实例。
- 数组。
-
特点:
- 是线程共享的区域。
- 垃圾回收(GC)主要针对堆区。
- 通常分为两部分:
- 年轻代(Young Generation):
- 分为 Eden 区、From Survivor 区、To Survivor 区。
- 新生对象首先分配在 Eden 区。
- 老年代(Old Generation):
- 存放生命周期较长的对象。
- (JDK 8 之前还包括永久代,JDK 8 后移除)
- 年轻代(Young Generation):
3. Java 栈区(Java Stack Area)
-
定义:
每个线程在创建时会分配一个独立的 Java 栈,存储线程执行的局部变量和方法调用信息。 -
存储内容:
- 方法调用的局部变量。
- 每个方法调用对应一个栈帧(Frame),存储局部变量表、操作数栈、方法返回值等。
-
特点:
- 是线程私有的。
- 方法调用结束后,栈帧会被销毁。
- 内存回收由系统自动完成。
4. 程序计数器(Program Counter Register)
-
定义:
程序计数器是一个小内存区域,用于记录当前线程正在执行的字节码指令地址。 -
存储内容:
- 当前线程执行的字节码指令地址。
- 如果正在执行本地方法(Native Method),此计数器值为空。
-
特点:
- 是线程私有的。
- 不会发生内存溢出。
5. 本地方法栈(Native Method Stack)
-
定义:
本地方法栈为本地方法(非 Java 方法,如通过 JNI 调用的 C 或 C++ 方法)提供服务。 -
存储内容:
- 本地方法的调用信息。
- 本地方法的变量和数据。
-
特点:
- 是线程私有的。
- 类似于 Java 栈,但专用于本地方法。
JVM 内存结构示意图
+--------------------+
| 方法区 | <- 类的元信息、静态变量等(线程共享)
+--------------------+
| 堆区 | <- 对象实例和数组(线程共享)
+--------------------+
| 本地方法栈 | <- 本地方法调用信息(线程私有)
+--------------------+
| Java 栈 | <- 方法调用的局部变量(线程私有)
+--------------------+
| 程序计数器 | <- 当前字节码指令地址(线程私有)
+--------------------+
总结
-
方法区和堆区:
- 是线程共享的,存储全局数据和对象实例。
-
Java 栈、程序计数器、本地方法栈:
- 是线程私有的,存储局部数据和执行上下文。
-
垃圾回收:
- 主要针对堆区,其他区域的内存由 JVM 自动管理。
JVM 的内存划分提供了强大的运行时支持,不同区域分工明确,保证了程序的高效运行和内存管理的安全性。
分类:
Java / JVM
, 面试题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2022-12-10 1691. 堆叠长方体的最大高度