JVM体系

news/2024/7/5 5:47:46

JVM是一种虚拟的计算机,它模拟了一个完整的硬件系统,并运行在一个完全隔离的环境中。这意味着JVM可以看作是一个在操作系统之上的计算机系统,与VMware、Virtual Box等虚拟机类似。JVM的设计目标是提供一个安全、可靠、高效且跨平台的运行环境,使得Java程序可以在任何装有JVM的平台上运行,实现“一次编译,多次运行”的特性。

JVM的体系架构主要包括以下几个部分:

类加载器(ClassLoader)

类加载器负责从文件系统或网络中加载.class文件,然后将其转换成Java类,以供JVM执行。JVM定义了三种类加载器:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。此外,用户还可以自定义类加载器。

类加载器的工作原理可以概括为三个步骤:加载、链接和初始化。

加载:类加载器首先会检查这个类的字节码文件是否已经被加载过,如果尚未加载,系统会初始化一个新的类。加载类的方式主要是从文件系统中读取.class文件,或者从网络获取.class文件,或者从zip、jar等归档包中读取.class文件,或者从其他来源动态生成.class文件。然后,类加载器将这个字节码文件的内容加载到内存中,并生成一个代表这个类的java.lang.Class对象,这个对象会被放入到Java堆内存中。

链接:链接包含验证、准备和解析三个阶段。验证是为了确保被加载的类文件信息符合JVM规范,没有安全方面的问题;准备是给类的静态变量分配内存,并设置默认的初始值;解析是将符号引用转换为直接引用,也就是将类中的符号引用(比如方法名)转换为实际的内存地址引用。

初始化:初始化阶段是执行类构造器方法的过程。此方法由编译器自动收集类中的所有类变量的赋值动作和静态代码块集合来生成的。

JVM提供了三种类型的类加载器:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。

启动类加载器:这是最顶层的加载类,主要加载核心类库,如rt.jar、resources.jar、charsets.jar等。它并不继承自ClassLoader,因为它在Java程序运行之前就已经被加载了。

扩展类加载器:这是启动类加载器的子加载器,它的父加载器是启动类加载器。它主要负责加载Java的扩展类库。

应用程序类加载器:这是扩展类加载器的子加载器,它的父加载器是扩展类加载器。它主要负责加载应用程序的类路径(CLASSPATH)上的类库。

这三种类加载器之间存在层级关系,形成了一种双亲委派模型。当一个类加载器收到了类加载请求,它首先不会自己先去加载,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中。只有当父类加载器无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。

类加载器的作用主要是实现类的动态加载,即只有在程序运行时才根据需要加载相应的类,而不是一次性加载所有的类。这种机制有助于减少程序启动时的内存开销,同时也可以避免加载无用的类,提高程序的运行效率。

运行时数据区

这是JVM在执行Java程序时使用的内存区域,主要包括方法区、堆、Java栈、程序计数器和本地方法栈。其中,方法区和堆是线程共享的,而Java栈、程序计数器和本地方法栈则是线程私有的。

方法区(Method Area)

方法区也被称为元空间(Metaspace)。它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。方法区是硬盘和CPU的中间桥梁,承载着操作系统和应用程序的实时运行。在HotSpot虚拟机中,方法区是线程共享的内存区域,它随着虚拟机的启动而创建,随着虚拟机的退出而销毁。

堆区(Heap)

堆区是垃圾收集器管理的主要区域,也被称为“垃圾收集堆”。堆区是线程共享的,它分为新生代和老年代。新生代主要存放新创建的对象,而老年代则存放存活时间较长的对象。堆区是JVM所管理的最大一块内存区域,几乎所有的对象实例都会在这里分配内存。

栈区(Stack)

每个线程在创建时都会创建一个虚拟机栈,每个方法在执行时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。栈区是线程私有的,每个线程都有自己的栈区,它的生命周期与线程的生命周期一致。栈区分为Java栈和本地方法栈。Java栈用于执行Java方法,而本地方法栈则用于执行native方法。

程序计数器(Program Counter)

程序计数器是一块较小的内存空间,也是运行速度最快的存储区域。它是线程私有的,每个线程都有一个自己的程序计数器,其生命周期与线程的生命周期一致。程序计数器用于指示当前线程所执行的字节码的行号指示器,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。它是程序控制流的指示器,分支、循环、跳转、异常处理和线程恢复等功能都需要依赖这个计数器完成。

执行引擎

执行引擎负责执行JVM中的字节码。它采用即时编译(JIT)技术,将字节码编译成机器码,以提高执行效率。此外,执行引擎还负责执行本地方法,即使用其他语言(如C和C++)编写的代码。

执行引擎主要包含以下几个部分:

解释器

当JVM启动时,解释器会根据预定义的规范对字节码进行逐行解释执行。解释器会“翻译”每条字节码指令为对应平台的本地机器指令,并执行这些指令。这种方式实现了Java的跨平台特性,因为字节码是平台无关的,只要有对应的解释器,就可以在任何平台上执行。

即时编译器(JIT Compiler)

即时编译器是另一种执行字节码的方式。与解释器不同,JIT编译器会将字节码直接编译成和本地机器平台相关的机器语言。这种方式可以提高程序的执行效率,因为编译后的机器代码通常比解释执行的代码运行得更快。JIT编译器通常会在程序运行时,根据程序的热点代码(频繁执行的代码)进行编译优化,以提高程序的性能。

执行引擎的工作过程如下:

指令获取

执行引擎在执行过程中,会根据程序计数器(Program Counter)来确定下一条需要执行的字节码指令。程序计数器是一个较小的内存空间,它记录了当前线程所执行的字节码的行号。每当执行完一项指令操作后,程序计数器就会更新为下一条需要被执行的指令地址。

指令执行

获取到指令后,执行引擎会将其解释或编译为本地机器指令,并在硬件上执行这些指令。这个过程可能会涉及到对本地方法栈的调用,以执行native方法(使用其他语言编写的代码)。


http://lihuaxi.xjx100.cn/news/2033613.html

相关文章

神经网络:卷积神经网络中的BatchNorm

一、BN介绍 1.原理 在机器学习中让输入的数据之间相关性越少越好,最好输入的每个样本都是均值为0方差为1。在输入神经网络之前可以对数据进行处理让数据消除共线性,但是这样的话输入层的激活层看到的是一个分布良好的数据,但是较深的激活层…

如何一键抠图换背景?分享两个好用的抠图方法

在数字化时代,图片编辑已成为日常生活和工作中不可或缺的一部分。而智能抠图软件,作为近年来兴起的图片处理技术,正引领着图片编辑的新篇章。它利用先进的机器学习和图像识别技术,能够自动识别和分离图片中的主体,实现…

踩坑实录(Fourth Day)

今天开工了,其实还沉浸在过年放假的喜悦中……今天在自己写 Vue3 的项目,虽说是跟着 B 站在敲,但是依旧是踩了一些个坑,就离谱……照着敲都能踩到坑,我也是醉了…… 此为第四篇(2024 年 02 月 18 日&#x…

题记(45)--字符串匹配

目录 一、题目内容 二、输入描述 三、输出描述 四、输入输出示例 五、完整C语言代码 一、题目内容 读入数据string[ ],然后读入一个短字符串。要求查找string[ ]中和短字符串的所有匹配,输出行号、匹配字符串。匹配时不区分大小写,并且可…

2023我患上了AI焦虑

2023我患上了AI焦虑 来自:宝玉 原文链接:https://baoyu.io/blog/ai/i-am-suffering-from-ai-anxiety-in-2023 2023 年对我来说是神奇的一年,我意外的从一个程序员变成了一个 AI 资讯届的“网红”,到年底的时候我在 X 平台的阅读量…

学习数据接构和算法的第10天

题目讲解 尾插 #include <stdio.h> #include <stdlib.h> // 定义顺序表结构 #define MAX_SIZE 100 struct ArrayList {int array[MAX_SIZE];int size; // 当前元素个数 }; // 初始化顺序表 void init(struct ArrayList *list) {list->size 0; // 初始时元素个…

PostgreSQL Error Codes (PostgreSQL错误代码)

Whats PostgreSQL Error Codes PostgreSQL服务器发出的所有消息都分配了五个字符的错误代码&#xff0c; 这些代码遵循 SQL 的"SQLSTATE"代码的约定。 需要知道发生了什么错误条件的应用程序通常应该检测错误代码&#xff0c;而不是查看文本错误消息。 这些错误代码…

pytorch入门笔记二

torch.nn.Sequential torch.nn.Sequential是一个容器&#xff0c;利用此容器可以快速简单的搭建一个简单的神经网络。这里以搭建一个三层神经网络为例。 首先该容器的参数分别是上一层到下一层的权重、激活函数&#xff0c;以此循环。 这里torch提供快速生成网络权重的方法&am…