Java内存区域分五部分:程序计数器(线程私有,存字节码地址,不OOM)、虚拟机栈(线程私有,存局部变量和操作数栈,可StackOverflow或OOM)、本地方法栈(线程私有,服务native方法)、堆(线程共享,存对象实例,GC主战场)、方法区(线程共享,存类信息等,JDK8后为元空间)。

面试时讲清楚 Java 内存区域,关键不是背名称,而是说清“谁用、存啥、共享还是私有、出错会怎样”这四点。下面按真实面试节奏组织,直接可用。
先总述五大区域,带逻辑主线
Java 虚拟机规范定义了五个运行时数据区:程序计数器、虚拟机栈、本地方法栈、堆、方法区。前三个是线程私有的,后两个是线程共享的。其中堆和方法区是内存管理重点,也是 OOM 最常发生的区域。
逐个说明要抓核心细节
• 程序计数器:每个线程独有一块极小内存,记录当前执行到哪条字节码指令。它是唯一不会发生 OutOfMemoryError 的区域。
• 虚拟机栈:线程私有,方法调用即入栈帧,帧里存局部变量(基本类型存值,引用存地址)、操作数栈等。栈深度超限抛 StackOverflowError;总内存不够则抛 OutOfMemoryError。
立即学习“Java免费学习笔记(深入)”;
• 本地方法栈:为 native 方法服务,HotSpot 里通常与虚拟机栈合用,面试提一句“实现上常合并”即可。
• 堆:所有线程共享,对象实例和数组都分配在这里。是 GC 主战场。JDK 7 起字符串常量池已从方法区移到堆中。
• 方法区:线程共享,存类信息、静态变量、常量、JIT 编译代码等。注意区分逻辑概念和 HotSpot 实现——JDK 8 前叫永久代(在堆内),JDK 8 起改用元空间(在本地内存),默认不受 JVM 堆大小限制,OOM 错误提示变为 “Metaspace”。
补充两个易忽略但常考的点
• 直接内存:不属于运行时数据区,是操作系统本地内存,通过 ByteBuffer.allocateDirect 分配。受 -XX:MaxDirectMemorySize 控制,超限报 “Direct buffer memory”。
• 字符串相关位置:String 字面量(如 "abc")存在字符串常量池;new String("abc") 中,对象本身在堆,字面量在常量池(JDK 7+ 在堆内),两者地址不同。
结尾可加一句收束
回答时把“规范定义”和“HotSpot 实现”分开说,比如“方法区是规范里的逻辑区,而元空间只是 JDK 8 后 HotSpot 对它的具体实现”,这样显得理解透彻,不被追问住。


















