编辑
2025-07-21
个人笔记
00

目录

概念
三大功能
JVM组成
JMM 内存模型
工作内存
程序计数器
虚拟机栈
本地方法栈
主内存

概念

JVM 全称是 Java Virtual Machine,中文译名 Java虚拟机。 JVM 本质上是一个运行在计算机上的程序,他的职责是运行Java字节码文件

三大功能

解释运行、内存管理和即时编译——JVM:我今天运行起来只为三件事(

  • 解释运行![[assets/JVM/file-20250508211934315.png]]

  • 内存管理

    • Java学长这招可太狠了,内存的分配和回收都交给JVM来处理,对程序员编写代码友好(jyy老师曾经说程序员是不可信的......因为会犯错)
  • 即时编译 对热点代码进行优化,提升执行效率。即时编译可以说是提升Java程序性能最核心的手段

    • Why?——优点
      • 实现跨平台
      • 提高性能
        • 热点代码——虚拟机是智能的,在运行的时候会发现某个方法被高频调用,就会对这段代码进行优化(在此处不做过多深入)
          • 优化——代码逻辑结构优化,更适合机器运行
          • 缓存——缓存解释过代码的字节码

JVM组成

![[assets/JVM/file-20250508215423528.png]]

  • 类加载器系统

    • 核心组件类加载器,负责将字节码文件(.class)中的内容加载到内存中
  • 运行时数据区

    • JVM管理的内存,创建出来的对象、类的信息等等内容都会放在这块区域中
  • 执行引擎

    • 解释器
      • 将字节码指令解释成机器码
    • 即时编译器(JIT Compiler)
      • 将热点代码(高频执行的代码)编译为本地机器码,提升性能
    • 垃圾回收器
      • 回收不再使用的对象
  • 本地方法接口(JNI, Java Native Interface)

    • 调用本地使用C/C++编译好的方法,本地方法在Java中声明时,都会带上native关键字

JMM 内存模型

JMM(Java Memory Model),官方名称为运行时数据区域

JVM在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。这里我们根据线程是否共享,可以简单地分为主内存和工作内存。![[assets/JVM/file-20250721162725868.png]]

  • 主内存
    • 所有线程共享的区域,包含了所有共享变量、类信息、实例对象等,也就是运行时数据区域中的堆和方法区的数据。
  • 工作内存
    • 每个线程在执行时的私有空间,包含了局部变量表、操作数栈等,也就是运行时数据区域中的程序计数器和栈的数据。

从上面主内存和工作内存的区分,当我们将JVM视作一个操作系统,两个内存。我们可以认为一个是程序里面的内存,负责运行程序中的变量、方法等数据;另外一个是我们计算机的内存,负责在我们电脑开机运行过程中数据的管理

工作内存

工作内存,也就是线程私有的内存,分为三个区域:

  • 程序计数器
  • 虚拟机栈
  • 本地方法栈

程序计数器

功能类似于CPU的PC计数器,但是在JVM中不同于CPU中的PC计数器,JVM中的程序计数器是每个线程独立拥有一个的

如此一来,各线程之间计数器互不影响,独立存储,便于线程切换后的恢复

程序计数器主要有两个作用:

  • 字节码解释器通过改变程序计数器来依次读取指令 (如:顺序执行、选择、循环、异常处理)
  • 多线程下,记录当前线程执行的位置

虚拟机栈

Java 虚拟机栈(后文简称栈)也是线程私有的,它的生命周期和线程相同,随着线程的创建而创建,随着线程的死亡而死亡。

回顾操作系统角度的JVM,虚拟机栈在这里作为程序(工作内存)的内部栈。一个程序在运行过程中是会调用很多方法,然后在各个方法之间进入返回,而栈的结构就类似方法之间的进出。

![[assets/JVM/file-20250721164540439.png]] 栈的每次压入弹出,就相当于我们进入方法、计算处理,然后返回结果。而在方法中又有许多信息需要存储和读取,所以栈中又有许多栈帧,每个栈帧中都拥有:

  • 局部变量表
    • 局部变量表 主要存放了编译期可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)。
  • 操作数栈
    • 主要作为方法调用的中转站使用,用于存放方法执行过程中产生的中间计算结果。另外,计算过程中产生的临时变量也会放在操作数栈中。
  • 动态链接
    • 主要服务一个方法需要调用其他方法的场景。Class 文件的常量池里保存有大量的符号引用比如方法引用的符号引用。当一个方法要调用其他方法,需要将常量池中指向方法的符号引用转化为其在内存地址中的直接引用。动态链接的作用就是为了将符号引用转换为调用方法的直接引用,这个过程也被称为 动态连接
  • 方法返回地址

本地方法栈

和虚拟机栈所发挥的作用非常相似,区别是:虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。

本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。

主内存

主内存是所有线程共享的内存