JVM 的内存区域是如何划分的?

文章目录

  • 一、线程私有区域
      • [1️⃣ 程序计数器(Program Counter Register)](#1️⃣ 程序计数器(Program Counter Register))
      • [2️⃣ Java 虚拟机栈(Java Stack)](#2️⃣ Java 虚拟机栈(Java Stack))
      • [3️⃣ 本地方法栈(Native Method Stack)](#3️⃣ 本地方法栈(Native Method Stack))
  • 二、线程共享区域(大家一起用)
      • [4️⃣ 堆(Heap)⭐重点](#4️⃣ 堆(Heap)⭐重点)
      • [5️⃣ 方法区(Method Area)](#5️⃣ 方法区(Method Area))
      • [6️⃣ 运行时常量池(Runtime Constant Pool)](#6️⃣ 运行时常量池(Runtime Constant Pool))
  • [三、JDK8 之后的重要变化(⚠️ 面试常问)](#三、JDK8 之后的重要变化(⚠️ 面试常问))
区域 线程 主要内容
程序计数器 私有 当前指令位置
虚拟机栈 私有 方法调用
本地方法栈 私有 Native 方法
堆 共享 对象实例
方法区 共享 类信息
运行时常量池 共享 常量、符号引用

一、线程私有区域

1️⃣ 程序计数器(Program Counter Register)

📍 干嘛的

  • 记录当前线程正在执行的字节码行号

  • JVM 靠它知道"下一条指令去哪"

📌 特点

  • 线程私有

  • 占用内存极小

  • 唯一不会抛 OutOfMemoryError 的区域

🧠 一句话记忆

👉 JVM 的"书签"


2️⃣ Java 虚拟机栈(Java Stack)

📍 干嘛的

  • 每个方法调用都会创建一个栈帧

  • 栈帧中包含:

    • 局部变量表

    • 操作数栈

    • 动态链接

    • 方法返回地址

📌 特点

  • 线程私有

  • 方法调用 → 入栈

  • 方法结束 → 出栈

💥 常见异常

  • StackOverflowError:递归太深

  • OutOfMemoryError:栈空间不够

🧠 一句话记忆

👉 方法调用的"通话记录"


3️⃣ 本地方法栈(Native Method Stack)

📍 干嘛的

  • 给 Native 方法(JNI) 用的栈

  • 例如调用 C / C++ 代码

📌 特点

  • 线程私有

  • 和虚拟机栈作用类似,只是服务对象不同

🧠 一句话记忆

👉 Java 调用"外援"的专用通道


二、线程共享区域(大家一起用)

4️⃣ 堆(Heap)⭐重点

📍 干嘛的

  • 几乎所有对象实例和数组都在这里分配

📌 特点

  • 线程共享

  • JVM 中 最大的一块内存

  • 垃圾回收(GC)的主战场

🧱 常见细分(HotSpot)

  • 新生代

    • Eden

    • Survivor(From / To)

  • 老年代

💥 常见异常

  • OutOfMemoryError: Java heap space

🧠 一句话记忆

👉 对象的"集中居住区"


5️⃣ 方法区(Method Area)

📍 干嘛的

  • 存储 类级别信息

    • 类结构信息

    • 方法信息

    • 运行时常量池

    • 静态变量

📌 特点

  • 线程共享

  • 逻辑上属于堆的一部分

💥 异常

  • OutOfMemoryError: Metaspace(JDK8+)

🧠 一句话记忆

👉 类的"说明书仓库"


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

📍 干嘛的

  • 存放:

    • 字面量(字符串、数字)

    • 符号引用(类、方法、字段)

📌 特点

  • 属于方法区的一部分

  • 运行期间也可以动态加入

🧠 一句话记忆

👉 JVM 的"常量词典"


三、JDK8 之后的重要变化(⚠️ 面试常问)

版本 变化
JDK7 方法区在堆中(永久代 PermGen)
JDK8 移除永久代
JDK8+ 方法区实现为 元空间 Metaspace(使用本地内存)
🧠 一句话记忆
👉 永久代下岗了,元空间接班,用的是系统内存
相关推荐
jingli914 小时前
一个测试用例把连接池卡死 30 秒:SQLite 连接池 max_size=1 下的重入自锁复盘
jvm·sqlite·测试用例
imDwAaY1 天前
Java中垃圾回收器 G1 和 CMS 有什么区别?
jvm·后端
xiaoqiMikko1 天前
JVM 线上排查实战(五):升 JDK 17 后进程起不来,十几个老 GC 参数挨个实测(完结)
java·jvm
Flynt1 天前
Java 27 悄悄改了 3 个默认值,我在 1 核小机器上逐个验证了一遍
java·jvm·性能优化
xiaoqiMikko1 天前
JVM 线上排查实战(三):grep BLOCKED 找不到的死锁,和 jstack 根本不报的死锁
java·jvm
此时不提桶,更待何时7 天前
01-06-A-JVM排查实战详解
java·jvm
wuminyu7 天前
HotSpot的轻量锁与膨胀后的ObjectMonitor状态重建原理
java·linux·c语言·jvm·c++
需要8267 天前
JVM 内存区域与对象创建:一次 GC 从哪来
java·jvm·spring boot·spring·servlet·tomcat
凤山老林7 天前
Spring Boot 应用 JVM 性能调优实战:GC 日志分析、堆内存规划与容器环境避坑
jvm·spring boot·gc·堆内存
需要8268 天前
Arthas 一个命令排查线上问题
java·jvm·spring·spring cloud