JVM扫盲:内存模型

JVM(Java Virtual Machine,Java 虚拟机)的内存模型是 Java 运行时数据区的规范,它定义了 JVM 在执行 Java 程序时如何管理内存。根据《Java 虚拟机规范》,JVM 的运行时数据区主要分为以下几个部分:


一、线程私有区域(Thread-Private)

这些区域是每个线程独立拥有的,生命周期与线程相同。

1. 程序计数器(Program Counter Register)

也叫PC寄存器,用于记录当前线程正在执行的字节码指令的地址,JVM 程序计数器 = 当前线程的"执行指针",保存当前线程的执行位置。

  • 如果当前线程正在执行的是一个 Java 方法,则程序计数器保存的是 JVM 字节码指令的地址。
  • 如果当前线程正在执行的是 Native方法,则程序计数器的值为 undefined。

Native方法:不是用Java写的方法,如System.currentTimeMillis();

举个例子:

java 复制代码
public void foo() {
    int a = 1;
    int b = 2;
    int c = a + b;
}

编译成字节码后:

bash 复制代码
0: iconst_1     // 将 1 压入操作数栈
1: istore_1     // 存入局部变量表 slot 1 (a)
2: iconst_2     // 将 2 压入栈
3: istore_2     // 存入 slot 2 (b)
4: iload_1      // 加载 a
5: iload_2      // 加载 b
6: iadd         // 相加
7: istore_3     // 存入 c
8: return       // 返回

PC寄存器记录的就是前面的数字,也就是当前执行到哪里了

2. 虚拟机栈(Java Virtual Machine Stack)

每当一个线程被创建,JVM 就会为它分配一个独立的虚拟机栈,虚拟机栈的核心单位是 栈帧(Stack Frame),每个方法调用都会创建一个栈帧,并在方法执行结束时销毁。栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

3. 本地方法栈(Native Method Stack)

与 Java 虚拟机栈类似,主要为虚拟机使用到的 Native 方法服务,在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。本地方法执行时也会创建栈帧,Native 方法运行在 JVM 之外(如 C 函数),其调用约定、栈帧格式与 Java 字节码不同,需要独立的管理机制

二、线程共享区域(Shared Among Threads)

这些区域被所有线程共享,随 JVM 启动而创建。

4. 堆(Heap)

是 JVM 中最大的一块内存区域,被所有线程共享,在虚拟机启动时创建,用于存放对象实例。从内存回收角度,堆被划分为新生代和老年代,新生代又分为 Eden 区和两个 Survivor 区(From Survivor 和 To Survivor)由 垃圾回收器(GC)自动回收不再使用的对象,程序员无需手动释放。

5. 方法区(Method Area)

在 JDK 1.8 及以后的版本中,方法区被元空间取代,使用本地内存。用于存储已被虚拟机加载的类信息、常量、静态变量等数据。虽然方法区被描述为堆的逻辑部分,但有 "非堆" 的别名。

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

是方法区的一部分,用于存放编译期生成的各种字面量和符号引用,具有动态性,运行时也可将新的常量放入池中。


三、直接内存(Direct Memory)

直接内存是堆外的本地内存,JVM 可以让操作系统直接把数据映射或共享到这块内存。不属于 JVM 运行时数据区的一部分,通过 NIO 类引入,是一种堆外内存,可以显著提高 I/O 性能。直接内存的使用受到本机总内存的限制

  • 不属于 JVM 运行时数据区,但被频繁使用(如 NIO 的 ByteBuffer.allocateDirect())。
  • 直接分配在操作系统内存中,不受 JVM 堆大小限制。
  • 但总内存仍受物理内存和操作系统限制,使用不当也会导致 OutOfMemoryError

相关推荐
万少13 分钟前
AtomCode开发微信小程序《谁去呀》 全流程
前端·javascript·后端
GetcharZp14 分钟前
Epic、暴雪都在用的 C++ 界面利器:Dear ImGui 零基础全景指南
后端
C+++Python1 小时前
详细介绍一下Java泛型的通配符
java·windows·python
pixcarp1 小时前
知识库系统的内容资产闭环怎么设计
服务器·数据库·后端·golang
红尘散仙1 小时前
别再手动录屏了:用 VHS 给终端应用生成会动的文档素材
后端·rust
JosieBook2 小时前
【数据库】时序预测能力的分级进化:TimechoAI如何让每一类用户都能精准预见未来
java·开发语言·数据库
江畔柳前堤2 小时前
github实战指南01-账号配置与 SSH 密钥
运维·人工智能·深度学习·ssh·github·pyqt·信号处理
一生了无挂2 小时前
Java处理JSON技巧教学(从基础到高阶实战全覆盖)
java·开发语言·json
李白的天不白3 小时前
使用 SmartAdmin 进行前后端开发
java·前端
swordbob3 小时前
Spring 单例 Bean 是线程安全的吗?
java·开发语言