jvm内存模型图(jvm内存模型有哪些)

jvm内存模型图(jvm内存模型有哪些)1 什么是 JVM JVM Java Virtual Machine Java 虚拟机 是执行 Java 字节码的虚拟环境 它将 Java 源代码编译成字节码 使得程序可以在各种操作系统和硬件上跨平台运行 而无需重新编译 JVM 负责加载字节码 解释或编译字节码为机器码 并提供自动内存管理 垃圾回收等功能 JVM 的主要功能 跨平台支持 自动内存管理 性能优化 多线程支持



1、什么是JVM

JVM(Java Virtual Machine,Java虚拟机)是执行Java字节码的虚拟环境,它将Java源代码编译成字节码,使得程序可以在各种操作系统和硬件上跨平台运行,而无需重新编译。JVM负责加载字节码、解释或编译字节码为机器码,并提供自动内存管理、垃圾回收等功能。

JVM的主要功能: 跨平台支持、自动内存管理、性能优化、多线程支持、安全性以及诊断和监控。

2、JVM整体结构

JVM (Java Virtual Machine)的整体结构可以分为五个主要部分:类加载子系统、运行时数据区、执行引擎、本地方法接口和运行时类库。分别负责不同的功能模块,为 Java 程序的执行提供支持。

在这里插入图片描述

2.1、类加载子系统

类加载子系统负责将Java字节文件 (.class文件)加载到JVM中,将其转换JVM能够执行的类对象。类加载过程按需加载,解决类的依赖关系。

类加载过程

(1) 加载: 通过类的全限定名获取类的字节码,并将其加载到内存中,生成 Class 对象。

(2) 验证: 校验字节码文件的正确性。

(3) 准备: 给类的静态变量分配内存,并赋予默认值。

(4) 解析: 将常量池的符号引用替换直接引用。

(5) 初始化: 执行类中的静态初始化块,给静态变量赋值。

四种类加载器

(1) 引导类加载器(Bootstrap ClassLoader): 负责加载支撑JVM运行的核心类库,位于JRE的lib目录,比如rt.jar、charsets.jar等。

(2) 扩展类加载器(Extension ClassLoader): 负责加载支撑JVM运行的扩展目录中的JAR类包,位于JRE的lib目录下的ext目录。

(3) 应用类加载器(Application ClassLoader): 负责加载ClassPath路径下的类包,主要加载自己写的类。

(4) 自定义类加载器(Custom ClassLoader): 负责加载用户自定义路径下的类包。

类加载的双亲委派机制

工作原理: 加载某个类时会先委托父加载器寻找目标类,找不到再委托上层父加载器加载。如果所有父加载器在自己的加载类路径下都找不到目标类,则在自己的类加载器路径中查找并载入目标类。

目的: 避免类的重复加载,保证被加载类的唯一性。

优势: 沙箱安全机制,防止核心API库被随意篡改,比如自己写的类不会被加载。

2.2、运行时数据区

运行时数据区包含五部分:线程共享的堆和方法区,线程私有的虚拟机栈、本地方法栈和程序计数器。

(1) 堆(Heap): 存储所有对象实例和数组。管理不同生命周期的对象,分年轻代(Eden、Survivor)和老年代。

(2) 方法区(Method Area): 存储类的元数据:类结构、方法定义、静态变量和运行时常量池等。

(3) 虚拟机栈(JVM Stack): 存储方法调用时的局部变量、操作数栈和方法返回地址等数据。数据以栈帧形式存在,每个栈帧对应一个方法调用。

(4) 本地方法栈(Native Method Stack): 支持本地方法的调用,存储调用本地方法时的局部变量、操作数栈等数据。执行非Java的本地方法。

(5) 程序计数器(Program Counter, PC Register): 记录当前线程执行的字节码指令的地址,随线程切换改变。

2.3、执行引擎

执行引擎执行Java字节码,将字节码转换为机器指令。由解释器、即时编译器和垃圾收集器组成。

解释器: 将字节码逐条解释为机器指令并执行,执行未经过JIT编译的字节码。

即时编译器: 将高频调用的字节码块编译为机器码,将热点代码直接转换为本地机器代码。

垃圾收集器: 执行垃圾回收,释放不再使用的对象占用的内存。

2.4、本地方法接口

本地方法接口提供与本地代码(如C、C++)进行交互的接口,允许Java调用非Java代码。

使用场景: 访问底层系统资源可已有的本地库(如操作系统API),进行高性能操作。

2.5、运行时类库

提供支持Java应用程序运行的核心类库,比如Java核心API、I/O网络和数据结构等。通常以.jar文件形式提供。

3、JMM内存模型
3.1、JMM简介

JMM内存模型 (Java Memory Model,简称JMM) 是Java语言中用于定义线程间通信与共享变量可见性的一种规范,目的是保证在多线程环境下数据的一致性和内存访问的有序性。JMM对变量的存储和读写进行了明确规定,并引入了“主内存”和“工作内存”的概念。

主内存(Main Memory): 所有线程共享的存储区域,所有变量(实例变量、静态变量等)都存储在主内存中。线程在主内存中的变量副本上进行操作,通过主内存实现不同线程间的通信。

工作内存(Working Memory): 每个线程都有自己的工作内存(类似于CPU缓存),其中存放了主内存中变量的副本。线程对变量的所有操作(读取、写入)都必须在工作内存中进行,而不是直接操作主内存。每个线程只能在自己的工作内存中看到这些变量的修改。

3.2、JMM关键问题

(1) 可见性: 保证当一个线程修改了变量后,其他线程能够立即看到变化。在JMM中通过关键字、锁(如、)实现可见性。

(2) 有序性: 保证代码的执行顺序与预期一致,避免重排序带来的执行不一致。JMM在没有依赖时允许指令重排序优化,但是通过“happens-before”规则确保在并发下操作的顺序。和锁机制也可以保证有序性。

(3) 原子性: 保证操作不可分割,要么完全执行要么完全不执行。简单变量的读取和写入是原子性的,但复合操作如自增等不是。锁和CAS操作可以确保复合操作的原子性。

3.3、内存操作规则

线程间通信规则

  • 线程对共享变量的读写需要经过主内存,线程的工作内存存储着共享变量的副本。
  • 所有的修改必须先同步回主内存,其他线程才能看到修改后的值。

happens-before 规则

JMM通过“Happens-Before”规则定义操作的顺序,来保证多线程环境下内存的可见性和一致性:

(1) 程序次序规则:单线程内,按代码的顺序执行。

(2) 锁定规则:一个锁的解锁操作,happens-before 后续对这个锁的加锁操作。

(3) volatile变量规则:对一个变量的写操作,happens-before 后续对该变量的读操作。

(4) 传递性:如果A happens-before B,B happens-before C,那么A happens-before C。

(5) 线程启动规则:Thread对象的start()方法happens-before线程的每一个操作。

(6) 线程中断规则:线程的interrupt()调用,happens-before 检查中断的代码。

4、我的公众号

敬请关注我的公众号:大象只为你,持续更新技术知识…

编程小号
上一篇 2025-02-20 18:17
下一篇 2025-02-17 11:40

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/60301.html