
这里需要先澄清一个关键点:JVM 内存结构(JVM Memory Structure) 和 Java 内存模型(Java Memory Model, JMM) 是两个不同的概念,但经常被混淆。
JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域各有用途,创建和销毁的时间也不同。根据《Java虚拟机规范》,JVM 内存结构(运行时数据区)如下图所示:

下面我们逐一详细讲解每个部分:
OutOfMemoryError 情况的区域。boolean, byte, char, short, int, float, long, double)、对象引用(reference 类型,它不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)和 returnAddress 类型(指向了一条字节码指令的地址)。StackOverflowError:如果线程请求的栈深度大于虚拟机所允许的深度(例如无限递归)。OutOfMemoryError:如果虚拟机栈可以动态扩展,但在扩展时无法申请到足够的内存。补充:本地方法栈 它与 Java 虚拟机栈的作用非常相似。区别在于:Java 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中,本地方法栈和 Java 虚拟机栈合二为一。

OutOfMemoryError:如果在堆中没有内存完成实例分配,并且堆也无法再扩展时。OutOfMemoryError:当方法区无法满足内存分配需求时。重要演进:方法区的实现
final 的常量值等。String 类的 intern() 方法。虽然不是 JVM 运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域,但它经常被使用,并且也可能导致 OutOfMemoryError。
java.nio 包引入的,通过 Native 函数库直接分配的堆外内存。DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为它避免了在 Java 堆和 Native 堆中来回复制数据。OutOfMemoryError。内存区域 | 线程共享? | 存储内容 | 是否可能 OOM / SOF |
|---|---|---|---|
程序计数器 | 私有 | 当前线程执行的字节码行号 | 不会 |
Java 虚拟机栈 | 私有 | 栈帧(局部变量表、操作数栈等) | SOF 和 OOM |
本地方法栈 | 私有 | Native 方法服务 | SOF 和 OOM |
Java 堆 | 共享 | 对象实例、数组 | OOM |
方法区 | 共享 | 类信息、常量、静态变量、JIT代码 | OOM |
运行时常量池 | 共享 | 字面量、符号引用(是方法区的一部分) | OOM |
直接内存 | N/A | NIO 使用的堆外缓冲区 | OOM |
理解 JVM 内存模型是理解 Java 程序运行机制、进行性能调优(尤其是 GC 调优)和故障诊断(如内存溢出)的基础。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。