JVM 的内存结构如何划分?

考查重点:线程私有与共享运行时区域。线程私有PC/栈,共享堆方法区,常量池属方法区,规范区域与实现布局分开

本题目录

参考答案

核心回答

按《Java虚拟机规范》的运行时数据区来讲,可以先分成两组:每个线程自己的程序计数器、Java 虚拟机栈,以及实现所需的本地方法栈;各线程共享的堆和方法区。运行时常量池属于方法区的一部分。

各区域的职责是:

  • 程序计数器:记录当前线程正在执行的 JVM 指令位置;执行 native 方法时,其值在规范中未定义。
  • Java 虚拟机栈:保存方法调用的栈帧。栈帧包含局部变量表、操作数栈,以及动态链接和方法返回等所需信息;方法正常返回或异常退出时,对应栈帧结束。
  • 本地方法栈:支持 native 方法等本地执行。它的具体结构和是否单独实现由虚拟机决定,不能直接套用 Java 栈帧的全部结构。
  • 堆:在规范抽象中,为类实例和数组分配空间,由各线程共享,是垃圾收集管理的重要区域。
  • 方法区:保存类级结构,例如字段和方法数据、方法代码、运行时常量池。规范规定职责,具体存储布局由虚拟机实现决定。

这里讨论的是运行时内存区域;JMM 则主要回答线程间共享变量的可见性、有序性等并发规则,两者需要区分。

堆和栈怎样配合?

假设一个方法创建了用户对象,并把引用保存在局部变量中。可以理解为:当前调用的栈帧保存局部引用,对象本身在堆中;另一个线程也可能持有指向同一个对象的引用。

因此,“栈是线程私有的”并不能推出“局部变量引用的对象一定不会被其他线程访问”。方法返回后,栈帧结束;若对象仍被其他可达引用持有,它也不会因为这个方法返回就立即回收。JIT 还可能消除部分对象的实际分配,不能把源代码中的每次 new 都直接等同于一次实际堆分配。

方法区、永久代和元空间是什么关系?

方法区是规范中的逻辑区域,永久代和元空间是讨论 HotSpot 实现时使用的概念。

HotSpot 在 JDK 8 移除了永久代,类元数据改由使用本地内存的元空间等设施保存;方法区所代表的职责仍然存在。不能把这理解成“规范删掉了方法区”,也不能把所有与类相关的数据和所有堆外内存都统称为元空间。

元空间同样有容量风险。以 JDK 25 的参数定义为例,-XX:MaxMetaspaceSize 可以限制类元数据使用的本地内存;未设置这个上限,也仍受可用本地内存和进程环境约束,并不代表不会溢出。

JVM 进程的内存只有这些吗?

运行时数据区是逻辑分类,排查进程内存时还需要看具体实现的物理占用,例如线程栈、元空间、JIT 代码缓存、NIO 直接缓冲区和其他本地库分配。

所以,-Xmx 限制 Java 堆,不能拿它当作整个 Java 进程的内存上限。直接内存也不是规范另外规定的一个运行时数据区;-XX:MaxDirectMemorySize 主要约束 NIO 直接缓冲区分配,不覆盖任意本地库的全部内存。

常见追问

哪些区域可能报内存相关错误? 栈所需深度超过允许范围可能抛 StackOverflowError;规范允许动态扩展的栈在扩展失败,或新线程初始栈无法分配时,可能抛 OutOfMemoryError。堆和方法区无法满足分配也可能 OOM。程序计数器则没有规范规定的 OOM 情形。

堆是否一定分为 Eden、两个 Survivor 和老年代? 这些是具体垃圾收集器的组织方式,不是所有 JVM 实现都必须采用的物理布局。回答运行时数据区时先说明堆的职责,再结合实际收集器讨论分代和 Region。

参考资料

相关面经

17 篇

浩鲸

AI应用开发工程师(java方向,国内)
秋招一面
查看原面经 →
jvm内存结构

水滴

AI 全栈工程师
校招秋招一面
查看原面经 →
进程和线程的区别?JVM中有哪些部分是线程共享的哪些是独有的?

去哪儿

AI 应用开发
查看原面经 →
JVM运行时数据区的核心构成,以及各区域的核心作用。

老虎国际

后端开发
实习一面、二面
查看原面经 →
Java内存管理是怎样的?垃圾回收机制是怎样的?

极兔速递

后端开发工程师
一面
查看原面经 →
JVM 内存区域划分
展开剩余 12 篇面经

蚂蚁集团

面经合集
查看原面经 →
说下 JVM 内存模型吧,JVM 的方法区和元空间有啥关系?元空间是完全替代方法区了吗?

蚂蚁集团

面经合集
查看原面经 →
JVM内存结构

广电数科

Java 开发工程师
实习
查看原面经 →
说一下JVM组成

顺丰

Java 开发工程师
秋招一面
查看原面经 →
jvm内存结构

去哪儿

AI 全栈开发工程师
查看原面经 →
JVM运行时的数据有哪些?各自有什么作用?

小鹏

后端开发工程师(AI / Agent 方向)
二面
查看原面经 →
讲一下 JVM 内存区域(线程私有部分、共享部分、方法区的演进)?

CVTE

AI 应用开发
一面
查看原面经 →
介绍一下java的jvm的内存是怎么划分的

字节跳动

后端开发工程师
社招一面、二面、三面
查看原面经 →
Java的运行内存有哪些? 你怎么理解堆和栈? 你知道 在数据层面上的二者本质区别吗?

滴滴

国际化后端开发
社招一面、二面、三面
查看原面经 →
介绍下jvm运行时数据区

阿里巴巴

Java 开发工程师
一面
查看原面经 →
JVM 里面主要的组件有哪些?JVM 的体系了解吗?能讲一下 JVM 的内存模型吗?

阿里巴巴

后端开发工程师(AI)
实习一面
查看原面经 →
说说 Java 的内存模型?堆和栈的区别是什么?

字节跳动

后端开发工程师(AI / Agent 方向)
四面
查看原面经 →
java内存模型 垃圾回收

相关题目

4 题