请添加图片描述

一句话总结

JVM内存模型主要包含堆(存放对象实例)、方法区(存储类信息、常量)、虚拟机栈(线程私有方法调用)、本地方法栈(Native方法)和程序计数器(线程执行位置)。堆和方法区线程共享,栈和程序计数器线程私有,直接内存通过堆外分配管理。

详细解析

Java 虚拟机(JVM)的内存区域分为多个部分,每个部分负责不同的任务。
在这里插入图片描述

1. 程序计数器(Program Counter Register)

作用:记录当前线程执行的位置(字节码指令的地址),确保线程切换后能恢复到正确的位置。
特点:
线程私有:每个线程独立存储,互不影响。
唯一无 OOM 的区域:不会抛出OutOfMemoryError。
Native 方法时值为空:执行本地方法(如 C/C++ 代码)时,计数器值为undefined。

2. 虚拟机栈(Java Virtual Machine Stacks)

作用:存储方法调用的栈帧(Stack Frame),每个方法从调用到完成对应一个栈帧的入栈到出栈。
结构:
局部变量表:存放基本数据类型(int,boolean等)、对象引用(指针)和返回地址。
操作数栈:执行字节码指令的临时数据存储区(如算术运算的中间结果)。
动态链接:指向运行时常量池的方法引用。
方法出口:记录方法返回的地址(正常返回或异常退出)。
异常:
StackOverflowError:栈深度超过限制(如无限递归)。
OutOfMemoryError:扩展栈时无法申请足够内存(较少见)。
线程私有:每个线程的栈独立分配。

3. 本地方法栈(Native Method Stack)

作用:为 Native 方法(非 Java 代码,如 JNI 调用)提供栈空间。
特点:
与虚拟机栈类似,但服务于本地方法。
HotSpot 虚拟机将两者合并。
异常:同虚拟机栈(StackOverflowError和OutOfMemoryError)。

4. 堆(Heap)

作用:存放对象实例和数组(所有线程共享的主内存区域)。
结构(分代模型):
新生代(Young Generation):
Eden 区:对象首次分配的区域。
Survivor 区(From/To):存活对象在 Minor GC 后暂存。
老年代(Old Generation):长期存活的对象(经过多次 GC 后晋升)。
元数据区(JDK8+):替代永久代,存放类元信息。
异常:OutOfMemoryError(堆内存不足)。
关键参数:
-Xms:初始堆大小。
-Xmx:最大堆大小。
-XX:NewRatio:新生代与老年代比例。
在这里插入图片描述

5. 方法区(Method Area)

作用:存储类信息(类名、方法、字段)、常量、静态变量、即时编译器代码。
演变:
JDK7 及之前:称为永久代(PermGen),受-XX:PermSize和-XX:MaxPermSize控制。
JDK8+:改为元空间(Metaspace),使用本地内存,由-XX:MetaspaceSize和-XX:MaxMetaspaceSize配置。
异常:OutOfMemoryError(类元数据过多)。

6. 运行时常量池(Runtime Constant Pool)

位置:方法区的一部分。
内容:
编译期生成的字面量(如字符串常量"abc")。
符号引用(类、方法、字段的全限定名)。
动态性:运行期间可添加新常量(如String.intern())。
异常:OutOfMemoryError(常量池溢出)。

7. 直接内存(Direct Memory)

作用:通过ByteBuffer.allocateDirect()分配的堆外内存,提升 NIO 性能。
特点:
不受 JVM 堆限制,但受系统内存影响。
由-XX:MaxDirectMemorySize控制大小。
异常:OutOfMemoryError(直接内存耗尽)。

8. 内存区域对比表

在这里插入图片描述

9. 常见问题示例

堆内存溢出:

List list = new ArrayList<>();
while (true) {
list.add(new Object()); // 不断创建对象,最终抛出 OOM
}
解决:增大-Xmx或优化代码减少对象创建。

元空间溢出:

// 动态生成大量类(如使用 CGLib)
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyClass.class);
enhancer.setCallback(…);
enhancer.create(); // 重复执行导致元空间 OOM
解决:增大-XX:MaxMetaspaceSize或限制动态类生成。

栈溢出:

public void recursiveMethod() {
recursiveMethod(); // 无限递归导致 StackOverflowError
}
解决:检查递归终止条件或增大-Xss(谨慎使用)。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐