JVM 内存模型面试精讲:堆、栈、方法区和元空间

JVM 内存模型是理解 Java 程序运行的基础。

JVM 运行时数据区

┌─────────────────────────────┐
│         方法区/元空间         │  ← 类信息、常量、静态变量
├─────────────────────────────┤
│            堆               │  ← 对象实例、数组
├──────────┬──────────────────┤
│  虚拟机栈  │   本地方法栈     │  ← 方法调用、局部变量
├──────────┴──────────────────┤
│         程序计数器           │  ← 当前线程执行位置
└─────────────────────────────┘

堆(Heap)

  • 存放所有对象实例和数组
  • 线程共享
  • GC 的主要区域
  • 分代:新生代(Eden + S0 + S1)+ 老年代

虚拟机栈(Stack)

  • 每个线程一个栈
  • 每个方法调用 = 一个栈帧
  • 栈帧包含:局部变量表、操作数栈、动态链接、返回值
  • StackOverflowError:栈深度超过限制(无限递归)
  • OutOfMemoryError:栈内存耗尽

方法区 → 元空间

JDK 7 的方法区(永久代)在 JDK 8 被移除,改为元空间(Metaspace)。

元空间使用本地内存(不是堆内存),解决了永久代的 OOM 问题。但如果不限制大小(-XX:MaxMetaspaceSize),理论上也会耗尽本地内存。

字符串常量池

JDK 7 开始从方法区移到堆里。为什么?方法区 GC 触发条件苛刻,字符串常量在堆里更容易被回收。

面试话术

JVM 内存分为线程共享的堆和方法区(元空间),以及线程私有的栈和程序计数器。堆存对象,栈存方法调用。JDK 8 的元空间替代了永久代,使用本地内存避免 OOM。

关键是要能说出每个区域存什么、什么时候会 OOM 或 StackOverflow。

关于 Zihao Zhang

后端开发工程师。关注 Java/Spring Boot/Redis/MySQL 技术栈,分布式系统,OLAP 数据库,AI Agent 开发与应用。

评论

评论已关闭。