JVM理论(二)类加载子系统

news2024/9/21 4:34:30

类加载流程

类加载流程
  • 类加载器子系统负责从文件系统或者网络中加载class文件,class文件的文件头有特定的文件标识(CAFEBABE是JVM识别class文件是否合法的依据)
  • classLoader只负责文件的加载,而执行引擎决定它是否被执行
  • 加载类的信息存放在运行时数据区的方法区中,方法区还包括常量池信息

 类加载过程由加载,链接,初始化构成

加载(Loading)

加载阶段需要完成以下三个过程:

  • 通过类的全限定名来获取其定义的二进制字节流;
  • 将字节流所代表的静态存储结构转化为元空间(JDK8前称为方法区)的运行时数据结构;
  • 在堆Heap中生成一个代表这个类的java.lang.Class对象,作为对元数据空间中这些数据的访问入口;

类加载器

类加载器分类

引导类加载器

Bootstrap-ClassLoader基于C/C++实现,负责加载Java的核心类库JAVA_HOME\jre\lib\rt.jar,该加载器不继承自ClassLoader抽象类,并且只加载包名为java、javax、sun等开头类,一次保证对核心源码的保护

扩展类加载器

Extension-ClassLoader,基于Java语言,由sun.misc.Launcher$ExtClassLoader实现,派生于ClassLoader抽象类,从java.ext.dirs系统变量指定的路径中的加载类库,或者JDK安装目录jre\lib\ext目录下加载

系统类加载器

Application-ClassLoader,基于Java语言,由sun.misc.Launcher$ExtClassLoader实现,它负责加载环境变量ClassPath指定的类库,如果在应用程序中没有自定义类加载器,一般情况下作为程序中默认的类加载器

自定义类加载器

主要作用

  • 隔离加载类(如项目工程中的中间件需要引入自己jar包,为了避免与其他工程具有相同类的冲突,我们可以自定义类加载器,实现不同中间件的隔离)
  • 修改类加载方式
  • 扩展加载源
  • 防止源码泄漏

扩展

  • sun.misc.Launcher是java虚拟机的入口应用,扩展类和系统类(App)定义在Launcher类下
  • 加载器之间的关系只是包含关系,不是上层下层,也不是父子类的继承关系

双亲委派机制

双亲委派模式

Java虚拟机对class文件采用的是按需加载方式,即当需要使用该类时才会将它的class文件加载到内存生成class对象,而且在加载某个类class文件时,Java虚拟机采取的是双亲委派模式,即将请求交由父类处理,它是一种任务委派模式

委派执行流程

  1. 类加载器收到了类加载的请求时,不会自己先去尝试加载这个类,而是把请求委托给父加载器去执行
  2. 如果父加载器还存在父类加载器,则依次向上委托,因此类加载请求最终都应该被传递到顶层的启动类加载器中
  3. 如果父类加载器可以完成类加载请求,就直接成功返回,只有当父加载器在无法完成该加载,子加载器才会尝试自己去加载该类

沙箱安全机制

假设自定义一个类名为String且所在包为java.lang,在使用引导类加载器加载时会先加载JDK(rt.jar包下的java/lang/String.class)中的String类,因为这个类本来是属于jdk的,后面再次出现String类就会报错,以此保证核心源代码不被恶意篡改,这就是沙箱安全机制。

链接(Linking)

执行流程依次为验证->准备->解析

验证

其目的在于确保Class文件的字节流中包含的信息符合当前虚拟机的要求,保证加载类的正确性,不会危害虚拟机自身的安全
验证内容:

  • 文件格式验证:验证字节流是否符合Class文件格式的规范
  • 元数据验证:确保其描述的信息符合Java语言规范的要求
  • 字节码验证:确定程序语义符合逻辑
  • 符号引用验证:确保解析动作能正确执行

准备

为类的静态变量分配内存,并初始化为默认值,仅包括类变量(static修饰,不包括final-static修饰),这里也不会为实例变量分配初始化,实例变量会随着对象一块分配到Java堆内存中

比如:某类中定义一个静态变量:private static int i = 10;此时在准备阶段i = 0,在后续的初始化阶段才会被赋值为10

解析

将常量池中的符号引用转换为直接引用的过程,直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。解析主要针对类或接口、字段、类方法、接口方法、方法类型等,解析的动作实际是会随着JVM在执行完初始化之后再执行的。

初始化(Initialization)

  • 初始化就是执行类构造器clinit()方法的过程
  • 该方法不需要自定义,是javac编译器自动收集类中的所有类变量的显示赋值动作和静态代码块中的语句合并而来
  • 构造器方法中你指令按语句在源文件中出现的顺序执行
  • JVM要保证clinit()方法在多线程访问下的安全性,即被同步加锁

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

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

相关文章

【终端增强工具】这次,我把Terminal(终端)也接入ChatGPT了...

大家好,我是萌新程序员豆小匠。 为terminal(终端)增加自定义命令这个想法从开始学编程的时候就有了,但是一直没有付诸行动。 这次,终于抽时间完成了,且代码开源! 实现的功能 先说下实现的功能…

Idea社区版创建SpringBoot

一 下载Spring Initalizr and Assistant插件 选择左上角的File->Settings->Plugins,在搜索框中输入Spring,出现的第一个Spring Boot Helper插件,点击Installed,下载插件。(这里已经下载) 二 创建Spr…

Python学习笔记【01-基础语法】

文章目录 第一章输入输出print转义字符字符编码标识符和保留字变量数据类型整形浮点型布尔类型字符串类型数据类型转换 注释 第二章input()函数运算符算术运算符赋值运算符比较运算符布尔运算符(逻辑运算符)位运算符运算符的优先级 第三章顺序结构对象的布尔值单分支结构双分支…

dSYM文件是什么 ?

Overview 概述 dSYM的全称是debug symbol, 所以dSYM文件就是debug symbol (dSYM) file, dSYM文件中的每个 debug symbol, 对应了一个关系, 这个关系一端是源代码里真实的符号(类名称、全局变量以及方法和函数名称), 另一端则是其定义的文件号和行号. Apple Documentation 苹果…

word批量替换时使用通配符

替换这个好操作,打开替换功能: 弹出窗口中分别输入要替换的对象和替换的结果: 这里主要介绍特殊的替换: 可以看到点击“更多”之后,会出现下面的选项 像是【区分大小写】、【全字匹配】、【同音】、【查找单词的所有形…

三张表学会MySQL的单表操作!

表单一信息 1、查询表中所有学生的信息 mysql> select * from student; 2、 查询表中所有学生的姓名和英语成绩 mysql> select name,english from student; 3、过滤表中的重复数据 mysql> select DISTINCT * from student; 4、统计每个学生的总分 mysql> sele…

大语言模型高效训练基础知识:优化器AdamW和Adafator

Prerequsite:Adam优化算法 Adam优化算法很长一段时间都是比较主流的参数更新算法,也有很多变种,本文介绍在大模型训练过程中使用的AdamW和Adafator AdamW 原论文:Decoupled Weight Decay Regularization AdamW指的是Adam Weight Decay&#…

Mysql中默认自动事务autocommit关闭和开启方式、rollback回滚恢复数据的使用方法

文章目录 autocommit自动提交事物一、查看autocommit状态二、修改autocommit 状态的方式1、第一种方式2、修改mysql配置文件my.cnf 二、rollback回滚1、autocommit 开启1、autocommit 关闭 autocommit自动提交事物 MySQL 默认开启事务自动提交模式,每条 SOL 语句都…

深度神经网络知识蒸馏算法基础理论

知识蒸馏作为一种压缩方法,与剪枝、量化中直接在原模型上进行参数的剪枝或数据位宽的降低来压缩不同,知识蒸馏方法往往是通过将大模型上的精度转移到一个相对更小的模型上来完成对大模型的压缩。此处所说的大模型即知识蒸馏中的教师模型,而相…

【C语言】深入学习数组

👦个人主页:Weraphael ✍🏻作者简介:目前正在回炉重造C语言(2023暑假) ✈️专栏:【C语言航路】 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你…

进程间通信方法——匿名管道

什么是管道&#xff1f; 管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道” 什么是匿名管道 就是一个没有名字的管道。 #include <unistd.h> 功能:创建一无名管道 原型 int pipe(int fd[2]); 参数 fd&#xff1a;文…

韩信谋反解密-使用命名空间

开机故事&#xff1a; 另一个韩信 什么是命名空间 c里面也有这种困扰&#xff0c;名字的冲突&#xff0c; 特意使用命名空间&#xff0c;开发的时候都要给函数命名 就会有名字相同的时候。这样就会出现混乱 区分相同名字相同函数的这样一个功能 用法1. #include<string…

openGauss学习笔记-04 openGauss极简版单机主备安装部署

文章目录 openGauss学习笔记-04 openGauss极简版单机主备安装部署4.1 获取安装包4.1.1 下载对应平台的安装包4.1.2 解压安装包4.1.3 查看目录结构 4.2 准备软硬件安装环境4.2.1 硬件环境要求4.2.2 软件环境要求4.2.3 软件依赖要求 4.3 单机主备安装部署4.3.1 安装前准备4.3.2 单…

【网络安全带你练爬虫-100练】第11练:xpath快速定位提取数据

目录 一、目标1&#xff1a;使用etree解析数据 二、目标2&#xff1a;使用xpath爬取指定数据 三、目标3&#xff1a;提取指定数据 四、网络安全小圈子 一、目标1&#xff1a;使用etree解析数据 其余的不用过多介绍&#xff0c;前面的练习都给大家已经过了一遍 def get_page…

【沐风老师】3DMAX砖石墙地面生成工具插件使用方法详解

3dMax砖石墙地面生成工具插件&#xff0c;收集了一些用于创建石墙、石头路面和不规则石头图案的实用工具&#xff0c;以模拟墙壁和地面。脚本会自动烘焙法线贴图、AO贴图和高度贴图以供实时使用。 【主要特点】 1.可以生成真实的石墙、地面、不规则石块及石灰墙面&#xff0c;是…

4.5 x64dbg 探索钩子劫持技术

钩子劫持技术是计算机编程中的一种技术&#xff0c;它们可以让开发者拦截系统函数或应用程序函数的调用&#xff0c;并在函数调用前或调用后执行自定义代码&#xff0c;钩子劫持技术通常用于病毒和恶意软件&#xff0c;也可以让开发者扩展或修改系统函数的功能&#xff0c;从而…

oracle启动/关闭/查看监听+启动/关闭/查看数据库实例命令

启动oracle第一步启动监听&#xff0c;第二步启动数据库实例 &#xff08;1&#xff09;输入su oracle进入oracle用户状态 &#xff08;2&#xff09;这里的密码是你的root密码 1 启动/关闭/查看监听命令 &#xff08;1&#xff09;启动监听—— lsnrctl start &am…

C#学习之路-封装

封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中&#xff0c;封装是为了防止对实现细节的访问。 抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化&#xff0c;封装则使开发者实现所需级别的抽象。 C…

编码和调制

编码与调制 消息是以二进制的形式存放在数据当中的&#xff0c;这种数据的表现形式是信号&#xff0c;而信源发出的原始信号就叫做基带信号&#xff0c;基带信号又可以分为数字基带信号和模拟基带信号。 信号需要在信道中进行传输&#xff0c;信道分为模拟信道和数字信…

libdrm编译调试

本文主要介绍libdrm的代码下载、编译和调试的工作。新版本的libdrm不再采用configure && make的方式编译&#xff0c;而是改用meson && ninja编译方式&#xff0c;近些年很多多媒体的开源软件包的构建系统有向后者靠拢的趋势&#xff0c;典型的比如gstream及其…