JVM 运行时内存模型

JVM 运行时内存共分为虚拟机栈、堆、元空间、程序计数器、本地方法栈五个部分

java 复制代码
import com.test.domain.User;
public class Main{
	static int count = 0;
	public static void main(String[] args){
		run();
	}
	public static void run(){
		String name = "zhangsan";
		User user = new User();
	}
	
	public native void test();
}

JVM 的内存结构主要分为以下几个部分:

虚拟机栈

用来存储每个线程的执行信息,即每个线程都有自己独立的虚拟机栈。每个方法在执行时都会在虚拟机栈中创建一个对应的栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

比如上面的代码,在运行 main() 方法的时候,会先把 main() 方法压入 JVM 虚拟机栈;当 main 调用 run() 方法时,又会新建一个栈帧并将 run() 压入栈中。该栈帧的局部变量表中会存储 nameuser 这两个局部变量。


是 JVM 中最大的一块内存区域,被所有线程共享,在虚拟机启动时创建,用于存放对象实例。

仍以上面代码为例:new User() 会在堆内存中创建一个 User 对象,并返回其地址;run() 方法栈帧中的局部变量 user 则保存该对象的引用(即地址)。
从 JDK 7 开始,字符串常量池(String Table)被从方法区移入了堆内存 。因此,字面量 "zhangsan" 会被存放在堆中的字符串常量池里。
原因包括

  • 方法区(永久代)空间有限,大量字符串容易导致 OutOfMemoryError: PermGen space
  • 字符串对象本身就在堆中,将常量池也放在堆中更便于垃圾回收。

元空间(方法区)

在 JDK 8 之前称为"方法区",JDK 8 及以后由"元空间"实现,使用本地内存(而非 JVM 堆内存),用于存储已被虚拟机加载的类元数据,包括:类结构信息、字段和方法的描述信息(如名称、类型、访问标志)、方法字节码、运行时常量池(非字符串对象)等。

仍以上述代码为例:public class Main 的类信息、static int count = 0;字段描述 (如字段名 "count"、类型 int、修饰符 static)等都会被加载到元空间中。
注意 :静态变量的 (如 count = 0)并不直接存在元空间,而是作为 Main.class 对象的一部分,存储在 Java 堆 中。

🔍 拆解说明:static int count = 0; 到底存哪?
内容 存储位置 说明
字段名 "count"、类型 int、访问标志 static 元空间 属于类的元数据,用于反射、JIT 编译等
静态变量的值 0 Java 堆 作为 Main.class(Class 对象)的一个字段值存储
Main.class 这个对象本身 Java 堆 在 JDK 8+ 中,所有 Class 对象都在堆中

因此,当你访问 Main.count 时,JVM 实际是从堆中的 Main.class 对象里读取这个值。


程序计数器

用于记录当前线程正在执行的 Java 方法的 JVM 字节码指令地址。每个线程都有独立的程序计数器。当线程切换时,程序计数器能确保线程恢复执行时从正确的位置继续。

如果当前执行的是 Native 方法,程序计数器的值为 undefined。


本地方法栈

与 Java 虚拟机栈作用类似,但专为虚拟机调用 Native 方法(如 C/C++ 编写的代码)服务。在 HotSpot 虚拟机中,本地方法栈和 Java 虚拟机栈实际是合二为一 的。本地方法执行时也会创建栈帧,同样可能出现 StackOverflowErrorOutOfMemoryError

上面代码中的 public native void test(); 方法,其调用过程由本地方法栈支持。


总结

JVM 运行时内存主要分为五部分:虚拟机栈、堆、元空间(方法区)、程序计数器、本地方法栈。其中堆和元空间是线程共享的,其余均为线程私有。


作者:不会写程序的未来程序员

首发于 CSDN

版权声明:本文为原创文章,转载请注明出处。

相关推荐
Thera7773 分钟前
状态机(State Machine)详解:原理、优缺点与 C++ 实战示例
开发语言·c++
2501_9061505617 分钟前
私有部署问卷系统操作实战记录-DWSurvey
java·运维·服务器·spring·开源
better_liang29 分钟前
每日Java面试场景题知识点之-TCP/IP协议栈与Socket编程
java·tcp/ip·计算机网络·网络编程·socket·面试题
niucloud-admin41 分钟前
java服务端——controller控制器
java·开发语言
To Be Clean Coder42 分钟前
【Spring源码】通过 Bean 工厂获取 Bean 的过程
java·后端·spring
Fortunate Chen1 小时前
类与对象(下)
java·javascript·jvm
程序员水自流1 小时前
【AI大模型第9集】Function Calling,让AI大模型连接外部世界
java·人工智能·llm
‿hhh1 小时前
综合交通运行协调与应急指挥平台项目说明
java·ajax·npm·json·需求分析·个人开发·规格说明书
小徐Chao努力1 小时前
【Langchain4j-Java AI开发】06-工具与函数调用
java·人工智能·python
无心水1 小时前
【神经风格迁移:全链路压测】33、全链路监控与性能优化最佳实践:Java+Python+AI系统稳定性保障的终极武器
java·python·性能优化