JVM 类加载子系统

1. 前言

​ 虚拟机就是一款用来执行虚拟计算机指令的计算机软件。它相当于一台虚拟计算机。大体上,虚拟机分为系统虚拟机和程序虚拟机。系统虚拟机就相当于一台物理电脑,里面可以安装操作系统;程序虚拟机是为了执行单个计算机程序而设计出来的虚拟机。其中 Java 虚拟机就是执行 Java 字节码指令的虚拟机

JVM 是什么?

java 虚拟机是运行在各大平台的执行字节码文件的虚拟计算机。如下图所示

这样的设计可以让编译后的代码在各个操作平台上运行。

JVM 的位置

JVM 在 Java 体系结构中的位置

从用户操作角度看 JVM 所处的位置

JVM 与实际的计算机硬件没有交互,它们中间还有个操作系统,调用硬件需要通过操作系统来实现。

JVM 的结构

JVM 的整体运行结构

本文主要针对于 Hotspot VM 来进行,其结构如下所示:

JVM 的指令结构

JVM 是基于栈的指令集架构,跟基于寄存器的指令集不同。它是一个步骤一个一条指令。

//基于栈的指令集
iconst_2 //常量2入栈
istore_1
iconst_3 // 常量3入栈
istore_2
iload_1
iload_2
iadd //常量2/3出栈,执行相加
istore_0 // 结果5入栈
//基于寄存器的指令集
mov eax,2 //在eax寄存器中的值设为2
add eax,3 //将eax寄存器中的值加3   

举例说明:

/*** @author wjw* @date 11/3/2021*/
public class StackStruTest {public static void main(String[] args) {int i = 2 + 3;/***0: iconst_5*1: istore_1*2: return*/int i = 2;int j = 3;int k = i + j;/*** 0: iconst_2* 1: istore_1* 2: iconst_3* 3: istore_2* 4: iload_1* 5: iload_2* 6: iadd* 7: istore_3* 8: return*/try {Thread.sleep(6000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello");}
}
JVM 的生命周期

JVM 的启动

Java 的启动是通过引导类加载器(BootStrap ClassLoader)创建一个初始类(java.lang.class)来实现的,也就是后面要提到的子类加载器过程。

JVM 的执行

执行 Java 的字节码文件中的各个方法和类的过程。

JVM 的退出

  • 程序正常执行结束
  • 操作系统终止 JVM 进程终止
  • 某线程调用 Runtime.exit() 或 System.halt() 方法
  • 程序执行过程异常或错误而终止退出

2. 类加载子系统的主要流程

让我们先看看一个 java 程序执行的流程是怎样的:

  • 首先一个 java 文件编写完后,经过 java 编译器生成 .class 文件
  • 这个 .class 文件经过类加载器,加载各类的 jar 包,以及该程序所需要的三方类的 .class 文件。并生成 java.lang.class 对象,这个对象将作为程序访问方法区中的这些类型数据的外部接口
  • . class 文件经过解析执行和 JIT 编译器编译执行,并调用操作系统相关指令来完成 java 程序。

而类加载子系统涉及到的过程有类加载器、字节码校验器和翻译字节码这几个过程:

加载阶段(Loading)

加载阶段(Loading)是类加载阶段(Class Loading)的一部分。在加载阶段中,.class 文件将经过三个类加载器的加载后才能进入下一个阶段。该阶段主要的作用(也就是上面 java 程序执行中的类加载器阶段)有:

  • 将各种各样格式的 .class 文件(jar 包,网络中,动态代理等等)读取并生成一个字节流,并转换成方法区中的运行时数据结构
  • 在内存中生成一个 java.lang.Class 对象,这个对象将作为程序访问方法区中的这些类型数据的外部接口

在类加载器中,主要分为两类:引导类加载器自定义类加载器

引导类加载器(Bootstrap ClassLoader)
  • 使用的是 C/C++ 来实现的,无法访问到,调用getClassLoader() 函数是为null。

  • 加载的类是一些核心类库,lib/home 下的类库。比如说是 Object 、String 等等 JVM 自身运行需要的类

  • 是其他加载器的父类吗?是的,但是无父类加载器

自定义类加载器(User-Defined ClassLoader)

派生于抽象类 ClassLoader 的类加载器

  • (1)拓展类加载器(Extension ClassLoader)

    • 父类加载器为 BootStrap ClassLoader

    • 主要加载的类是ext 文件夹下的类库

  • (2)应用程序类加载器(AppClassLoader)

    • 父类加载器为 Extension ClassLoader

    • 主要加载的是环境变量 classpath 或系统属性 java.class.path 指定路径下的类库

    • 程序中默认的类加载器

  • (3) 自定义类加载器

    • extCassLoader 和 AppClassLoader 是 sun.misc.Launcher 的两个内部类

为了防止虚拟机内部的核心类库的修改和非法调用,JVM 的设计者们在类加载过程中设计出了双亲委派机制沙箱安全机制

双亲委派机制
  • 当前类加载器先不加载,先委托其父类加载器,依次到启动加载器
  • 如果启动加载器还没找到所要的类,然后向下查找,到返回到最初的子类加载器
  • 类加载器之间的关系不是继承,而是通过组合来复用父加载器的代码。

举例

  • 首先在 Bootstrap ClassLoader 中加载核心 rt.jar 包中的核心类
  • 核心类中的一些三方接口在反向委派到应用程序加载器加载第三方的 jar 包
  • 是通过当前线程加载器(就是系统类加载器)加载到 jdbc.jar 包中的 SPI 接口实现类

双亲委派机制的优点:

  • 避免类的重复加载
  • 保护程序安全,防止核心 API 被随意篡改
沙箱安全机制

引导类加载器在加载时会首先加载 JDK 中自带的文件。报错信息中没有相应方法时的机制。保证对 java 核心源代码的保护。

链接阶段(Linking)
验证(Verify)

验证字节流文件中的相关信息,确认当前文件符合虚拟机的相关格式(文件、元数据、符号等等)。

准备(Prepare)

在方法区中为类变量分配内存并设置类变量初始值

  • 这里的类变量是指被 static 修饰的变量,不包括实例变量(实例变量在对象实例化时随着对象一起分配)
  • 初始值指的是数据类型的零值
解析(Resolve)
  • 虚拟机将常量池中的符号引用转换成直接引用(class 文件很小,先存放指向所需要类的符号,解析时再引用)

  • 针对类、接口、字段方法等7类符号引用进行转换

  • 没有规定解析阶段发生的具体时间,也可能在初始化阶段的后面

初始化阶段(Initiation)
  • 初始化过程实际上就是执行类构造器方法 ( ) 的过程

    • 它是 javac 编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来,不需要定义。
    public class ClassInitTest {private static int num = 1;static {num = 2;number = 20;System.out.println(num);//因为在linking 阶段中的 Prepare 阶段已经给静态变量赋过初始值了。//非法的前向引用;在声明变量之前,可以去给这些变量进行赋值,但是不能够调用它。//System.out.println(number);//会报错误}/**也就是在 linking 中的 prepare 中对变量进行默认赋值为0* 此时initial 给予其一个覆盖从 20 到 10**/private static int number = 10;public static void main(StringDemo[] args){System.out.println(ClassInitTest.num);System.out.println(ClassInitTest.number);}
    }
    
    • 它不需要显示调用父类构造器,在子类的( ) 执行前,父类的 ( ) 方法早已执行完毕。

  • 构造器方法执行是按语句顺序来执行的。

  • 类构造器方法 ( ) 和类构造器( ) 并不是一回事

    • ( ) 方法不需要定义,而( ) 需要定义(不定义但是会有个默认为空的构造器方法)
    • 只有当代码中包含 static 变量时,才会执行 ( ) 方法,而( ) 所有类的字节码中都有


  • 在多线程时,初始化只执行一次,否则会被上锁

3.其他小结

  • 确定两个类是否相同
    • 包名、类名完全相同
    • 所用的类加载器也要相同
  • 类的主动使用和被动使用
    • 也就是是否有初始化过程,是否调用 clinit<>() 方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/577929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux文件编程

目录 1、Linux系统提供的文件编程API 1.1打开文件&#xff1a;open 1.2创建文件creat函数 1.3写入文件write函数 1.4读取文件read函数 1.5文件光标位置lseek函数 2、另外一组文件编程API 2.1文件打开函数fopen 2.2读文件函数fread 2.3写文件函数fwrite 2.4文件光标位…

vscode中使用GitHub Copilot Chat

文章目录 一、什么是Github Copilot Chat二、安装使用三、如何使用1. 聊天功能2. 内联功能 一、什么是Github Copilot Chat GitHub Copilot Chat 由 OpenAI 的 GPT-4 大型多模态模型提供支持&#xff0c;能带来更准确的代码建议、解释和指导。GitHub Copilot Chat 的内联功能可…

手机上的软件怎么修改网络IP地址

在手机上修改网络IP地址通常需要通过以下两种方法&#xff1a; 1. 使用VPN&#xff08;虚拟私人网络&#xff09;或代理软件&#xff1a; 步骤如下&#xff1a; - 下载并安装一个可靠的VPN或代理软件到你的手机上。 - 打开VPN或代理软件&#xff0c;选择一个你希望获取IP地址…

计算机毕业设计 基于SpringBoot的高校宣讲会管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

关于Python里xlwings库对Excel表格的操作(十九)

这篇小笔记主要记录如何【取消合并单元格】。 前面的小笔记已整理成目录&#xff0c;可点链接去目录寻找所需更方便。 【目录部分内容如下】【点击此处可进入目录】 &#xff08;1&#xff09;如何安装导入xlwings库&#xff1b; &#xff08;2&#xff09;如何在Wps下使用xlwi…

vue2、vue3实现用aws s3协议操作minio进行文件存储和读取

亚马逊s3 API文档 最开始安装了aws-sdk/client-s3&#xff0c;但是不知道为什么一直报错&#xff0c;所以用了aws-sdk 准备工作&#xff1a; 需要已经搭建好minio、创建好桶 1. vue2 安装插件 yarn add aws-sdk s3配置 var AWS require("aws-sdk"); AWS.co…

解析翻页设计的最佳实践和后端设计概要

文章目录 解析翻页设计的最佳实践和后端设计概要缘起BFF评审中的翻页问题AuditLog翻页问题的处理分页设计思考 关键点总结进一步思考 解析翻页设计的最佳实践和后端设计概要 缘起 在技术开发过程中&#xff0c;翻页操作的设计常常涉及到多种需求和技术考量。回顾最近的讨论和…

阿里云 ECS Docker、Docker Compose安装

https://help.aliyun.com/document_detail/51853.html https://docs.docker.com/compose/install/ Centos https://blog.csdn.net/Alen_xiaoxin/article/details/104850553 systemctl enable dockerdocker-compose安装 https://blog.csdn.net/qq465084127/article/details/…

CentOS 8.2 安装 Mysql 5.7.26(单机)

Mysql二进制包: mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz 1、卸载旧环境 rpm -qa|grep mysql rpm -qa|grep mariadb rpm -e XXX.rpm --nodeps # 强制卸载rpm包 rm -rf /etc/my.cnf rm -rf /etc/mysql rm -rf /usr/local/mysql 2、安装依赖包 yum -y install libaio yum…

vscode括号颜色突然变成白色的了,怎么解决

更新版本后发现vscode的各种括号都变成了白色&#xff0c;由于分色括号已经使用习惯&#xff0c;突然变成白色非常不舒服&#xff0c;尝试多次后&#xff0c;为大家提供一下几种解决方式&#xff0c;希望能帮到同样受到此种困惑的你&#xff1a; 第一种&#xff1a; 首先打开…

WebGL开发建筑和设计教育应用

使用 WebGL 开发建筑和设计教育应用可以为学生提供沉浸式的三维体验&#xff0c;使他们能够在虚拟环境中探索建筑结构、材料和设计理念。以下是开发建筑和设计教育应用的一般步骤&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&…

计算机视觉基础(13)——深度估计

前言 本节是计算机视觉的最后一节&#xff0c;我们将学习深度估计。从深度的概念和度量入手&#xff0c;依次学习单目深度估计和双目/多目深度估计&#xff0c;需要知道深度估计的经典方法&#xff0c;掌握深度估计的评价标准&#xff0c;注意结合对极几何进行分析和思考。 一、…

【LeetCode刷题笔记】动态规划(四)

背包问题 0-1 背包问题 有一个背包,它的容量为 C现在有 n 种不同的物品,他们的编号分别是 0...n-1。每一种物品只有一个。在这 n 种物品中,第 i 个物品的重量是 w[i],它的价值为 v[i]问题是:可以向这个背包中放哪些物品,使得在不超过背包容量的基础上,背包中物品的总价…

【华为OD题库-110】反转每对括号间的子串-java

题目 给出一个字符串s(仅含有小写英文字母和括号)。 请你按照从括号内到外的顺序&#xff0c;逐层反转每对匹配括号中的字符串&#xff0c;并返回最终的结果。注意&#xff0c;您的结果中不应包含任何括号。 示例1: 输入: s “(abcd)” 输出: “dcba” 示例2: 输入: s “(u(l…

MongoDB视图的修改与删除

目录 修改视图 删除视图 视图&#xff0c;为mongodb的操作和数据安全上提供了便利。但伴随着业务逻辑的发展或数据库维护人员操作当中产生的错误&#xff0c;视图难免需要维护修改。例如增加字段&#xff0c;修改视图中的计算逻辑等。 修改视图 查询mongodb的官方文档&…

Linux的基本命令

文章目录 grep的基本查询grep的高亮查询 grep的基本查询 grep命令可以用于在文件中查找指定内容&#xff0c;并将包含该内容的行打印出来。以下是几种不同的实现方法&#xff1a; 使用基本语法格式&#xff1a; &#xff08;1&#xff09;grep “要查找的内容” 文件名 例如…

【SpringCloud笔记】(10)消息总线之Bus

Bus 前言 戳我了解Config 学习Config中我们遇到了一个问题&#xff1a; 当我们修改了GitHub上配置文件内容&#xff0c;微服务需要配置动态刷新并且需要手动向客户端发送post请求刷新微服务之后才能获取到GitHub修改过后的内容 假如有多个微服务客户端3355/3366/3377…等等…

Android 手机对于Arduino蓝牙控制解决方案

1、Android系统概述 ​ Android 系统是 Google 公司基于 Linux 内核开发的移动端操作系统,适用于智能手机智能手表平板电脑等设备&#xff0c;最新的版本为 7.1。Android系统具有免费开源的优势,任何企业与个人都可以查阅公开的 API 文档&#xff0c;并在自己开发的应用中通过调…

xlua源码分析(四) lua访问C#的值类型

xlua源码分析&#xff08;四&#xff09; lua访问C#的值类型 上一节我们主要探讨了C#是如何使用interface和delegate访问lua层的table和function的&#xff0c;本节我们跟着Examples 05_NoGc&#xff0c;来看看xlua是如何实现lua层无gc访问C#的值类型的。 首先例子中用到的lua…

使用OpenSSL生成自签名SSL/TLS证书和私钥

使用OpenSSL生成自签名SSL/TLS证书和私钥 前提&#xff1a; 系统安装了OpenSSL&#xff1b; 系统&#xff1a;windows、linux都可&#xff1b; 1 生成私钥 创建一个名为 server.key 的私钥文件&#xff0c;并使用 RSA 算法生成一个 2048 位的密钥。 openssl genrsa -out s…