JVM类加载器面试题及原理

JVM只会运行二进制文件,类加载器的作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来。

1. 类加载器的种类

  • 启动类加载器(BootStrap ClassLoader):加载JAVA_HOME/jre/lib目录下的库
  • 扩展类加载器(ExtClassLoader):主要加载JAVA_HOME/jre/lib/ext目录中的类
  • 应用类加载器(AppClassLoader):用于加载classPath下的类
  • 自定义类加载器(CustomizeClassLoader):自定义类继承ClassLoader,实现自定义类加载规则。
    在这里插入图片描述

2. 双亲委派模型

2.1 原理

加载某一个类,先委托上一级的加载器进行加载,如果上级加载器也有上级,则会继续向上委托,如果该类委托上级没有被加载,子加载器尝试加载该类

  • student类在应用类加载器,向上委托,但lib和ext目录都没有student,所以向下由含有student类的子加载器(应用类加载器)加载student类
  • string类在应用类加载器,向上委托,lib目录下有,于是加载string类然后返回给应用类加载器让它直接使用
    在这里插入图片描述

2.2 使用场景

JVM为什么采用双亲委派机制?

  1. 通过双亲委派机制可以避免某一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性
  2. 为了安全,保证类库API不会被修改
    ex:
package java.long;
public class String{public static void main (Stringll args) {System.out.println("demo info");}
}

此时执行main函数,会出现异常,在类java.lang.String 中找不到 main 方法

错误:在类 java.Lang.string 中找不到 main 方法,请将 main 方法定义为:
public static void main(String[] args)
否则 JavaFX 应用程序类必须扩展
javafx.application.Application

报错原因:由于是双亲委派的机制,javalang.String的在启动类加载器得到加载,因为在核心jre库中有其相同名字的类文件,但该类中并没有main方法。这样就能防止恶意篡改核心API库。(所以这就是为什么类名不能是关键字的根本原因)

3. 类装载的执行过程

  • 类从加载到虚拟机中开始,直到卸载 止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。
  • 其中,验证、准备和解析这三个部分统称为连接(linking)
    在这里插入图片描述

3.1 加载阶段

查找和导入class文件

  • 通过类的全名,获取类的二进制数据流。
  • 解析类的二进制数据流为方法区内的数据结构(Java类模型)
  • 创建java.lang.Class类的实例,表示该类型。作为方法区这个类的各种数据的访问入口
    在这里插入图片描述

3.2 连接阶段

3.2.1 验证阶段

保证加载类的准确性
验证类是否符合JVM规范,安全性检查

  • 格式检查,如:文件格式是否错误、语法是否错误、字节码是否合规(1)(2)(3)
    1. 文件格式验证
    2. 元数据验证
    3. 字节码验证
  • Class文件在其常量池会通过字符串记录自己将要使用的其他类或者方法,检查它们是否存在(4)
    4. 符号引用验证
    在这里插入图片描述

3.2.2 准备阶段

内类变量分配内存并设置类变量初始值

  1. static变量,分配空间在准备阶段完成(设置默认值),赋值在初始化阶段完成
  2. static变量是final的基本类型,以及字符串常量,值已确定,赋值在准备阶段完成
  3. static变量是final的引用类型,那么赋值也会在初始化阶段完成
public class Application {static int b = 10;      //(1)static final int c = 20;   //(2)static final String d = "hello";   //(2)static final Object obj = new Object;  //(3)

3.2.3 解析阶段

把类中的符号引用转换为直接引用
比如:方法中调用了其他方法,方法名可以理解为符号引用,而直接引用就是使用指针直接指向方法

  • 符号引用:代#的是符号引用,符号引用可能也引用其他符号引用或直接引用类
  • 直接引用:找到符号指的类与方法去执行
    在这里插入图片描述

在这里插入图片描述

3.3 初始化阶段

对类的静态变量,静态代码块执行初始化操作

  • 如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。
  • 如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行。
//Animal是Cat父类
//子类初始化,如果父类还没初始化,会引发父类先初始化
System.out.println(Cat.sex);
//子类访问父类静态变量,只触发父类初始化
System.out.println(Cat.num);

3.4 使用阶段

JVM 开始从入口方法开始执行用户的程序代码

  • 调用静态类成员信息(比如:静态字段、静态方法)
  • 使用new关键字为其创建对象实例

3.5 卸载阶段

当用户程序代码执行完毕后,JVM便开始销毁创建的Class对象。

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

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

相关文章

C语言每日一练——day_3(快速上手C语言)

引言 针对初学者,每日练习几个题,快速上手C语言。第三天。(会连续更新) 采用在线OJ的形式 什么是在线OJ? 在线判题系统(英语:Online Judge,缩写OJ)是一种在编程竞赛中用…

用Qt手搓AI助手,挑战24小时开发DeepSeek Assistant!

一、项目需求分析与技术选型 DeepSeekAssistant是一款基于深度求索(DeepSeek)API的智能对话助手,核心需求包括: 用户界面友好:支持多轮对话展示数据持久化:历史记录存储与检索异步网络通信:AP…

Linux 环境变量快速上手指南

Linux 环境变量快速上手 1. 什么是环境变量 环境变量(Environment Variables)是操作系统中用于存储配置信息的一种机制,可以在运行时被进程读取和使用。常见环境变量示例: PATH: 存放可执行文件搜索路径。HOME: 当前用户的家目录…

万字技术指南STM32F103C8T6 + ESP8266-01 连接 OneNet 平台 MQTT/HTTP

此博客为一份详细的指南,涵盖 STM32F103C8T6 通过 ESP8266-01 连接 OneNet 平台,并使用 MQTT/HTTP 进行数据通信的完整流程。这份文档包括: OneNet 平台的介绍与功能概览在 OneNet 上创建和配置设备的方法STM32CubeIDE 的开发环境搭建ESP826…

Go本地缓存设计与实现

本地缓存是一个项目中很常见的组件。在很多人的眼中就是一个简单的key-value的map存储即可实现,但实际上,设计一个本地缓存需要考虑的问题远比你想象的多,比如说,本地缓存是将数据存储在内存,若数据量激增突破了内存限…

深入解析 JavaScript 原型与原型链:从原理到应用

原型和原型链是 JavaScript 中实现对象继承和属性查找的核心机制。为了更深入地理解它们,我们需要从底层原理、实现机制以及实际应用等多个角度进行分析。 1. 原型(Prototype) 1.1 什么是原型? 每个 JavaScript 对象&#xff08…

FPGA时序约束的几种方法

一,时钟约束 时钟约束是最基本的一个约束,因为FPGA工具是不知道你要跑多高的频率的,你必要要告诉工具你要跑的时钟频率。时钟约束也就是经常看到的Fmax,因为Fmax是针对“最差劲路径”,也就是说,如果该“最差劲路径”得到好成绩,那些不是最差劲的路径的成绩当然比…

Visual Studio Code打开远程服务器项目,打开服务器Android上百G源码,SSH免密连接方式

Visual Studio Code打开远程服务器项目 1,Visual Studio Code拓展中,安装远程插件 Remote Development 2,SSH免密连接,A电脑免密连接B,配置B电脑.ssh/authorized_keys A电脑的.ssh/id_rsa.pub中的公钥内容,…

AWS云编排详解-Cloud Formation

作者:私语茶馆 1.关键概念 名词 说明 软件: CloudFormation 描述AWS 资源、配置值和互连关系。借助集成设施即代码加快云部署 CloudFormation Designer 拖拽式图形化模板编辑界面。 Amazon Simple Notification Service (SNS) SNS可通过电子邮件跟踪堆栈的创建和删除进度,…

《PyQt5》——设计Python GUI(图形用户界面)实例

PyQt5 PyQt5的配置和基础使用可以参考这篇文章:《 PyQt5》—— 创建 Python GUI(图形用户界面) Python GUI(图形用户界面)实例 本实例是设计一个通过玉米和豆粕的价格来预测生猪的价格,并显示预测价格与实…

kali linux 打开 word

Kali Linux是一款专为网络安全领域而设计的操作系统,它集成了大量的安全工具,帮助用户进行网络渗透测试和安全评估。作为一款功能强大的操作系统,Kali Linux可以满足用户在网络安全领域的各种需求,包括渗透测试、漏洞分析、数字取…

hooks useModule自定义hooks (二次封装AgGridReact ag-table)自定义表头,自定义表头搜索

场景业务: 多次运用AgGridReact的table 列表 思路: 运用自定义hooks进行二次封装: 通用配置例如:传参的参数,传参的url,需要缓存的key这些键值类 定制化配置例如:需要对table 的一些定制化传…

SpringBoot最简单方式实现自定义异常页面(404)

最简单的方式实现所有自定义异常页面(如 404、500 等)是通过 静态资源文件 或 模板引擎 来实现。 方法 1:使用静态资源文件(最简单) Spring Boot 默认会在 src/main/resources/static 或 src/main/resources/public …

django下防御race condition漏洞(竞争型漏洞)

目录 竞争型漏洞 概念 常见类型及示例 环境搭建 ​编辑漏洞复现 ucenter/1/ ucenter/2/ ucenter/3/ ucenter/4/ 总结 悲观锁 乐观锁 竞争型漏洞 概念 竞争型漏洞,也称为竞态条件漏洞(Race Condition Vulnerability),…

用Python写一个算24点的小程序

一、运行界面 二、显示答案——递归介绍 工作流程&#xff1a; 1. 基本情况&#xff1a;函数首先检查输入的数字列表 nums 的长度。如果列表中只剩下一个数字&#xff0c;它会判断这个数字是否接近 24&#xff08;使用 abs(nums[0] - 24) < 1e-10 来处理浮点数精度问题&…

PostgreSQL 18新特性之虚拟生成列

PostgreSQL 12 提供了生成列&#xff08;GENERATED ALWAYS AS STORED&#xff09;功能&#xff0c;但是只能支持存储型的生成列&#xff0c;需要占用存储空间&#xff0c;更新成本高。 为此&#xff0c;PostgreSQL 18 即将引入一个新的增强&#xff1a;虚拟生成列。这种类型的…

GitHub上传项目

总结&#xff08;有基础的话直接执行这几步&#xff0c;就不需要再往下看了&#xff09;&#xff1a; git init 修改git的config文件&#xff1a;添加:[user]:name你的github用户名 email你注册github的用户名 git branch -m master main git remote add origin 你的URL gi…

常见排序算法深度评测:从原理到10万级数据实战

常见排序算法深度评测&#xff1a;从原理到10万级数据实战 摘要 本文系统解析冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序和基数排序8种经典算法&#xff0c;通过C语言实现10万随机数排序并统计耗时。测试显示&#xff1a;快速排序综合性能最优&…

动态规划填表技巧:固定最后一个数 vs 固定倒数第二个数

在动态规划中&#xff0c;填表时固定最后一个数还是倒数第二个数&#xff0c;取决于问题的定义和状态转移方程的设计。 目录 1. 固定最后一个数 适用场景 特点 示例 2. 固定倒数第二个数 适用场景 特点 示例 3. 固定最后一个数与倒数第二个数的对比 4. 总结 1. 固定最…

【C】链式二叉树算法题2

目录 1 另一棵树的子树 1&#xff09; 题目描述 示例1&#xff1a; 示例2&#xff1a; 2&#xff09; 算法解析 3&#xff09; 代码 2 二叉树的遍历 1&#xff09; 问题描述 2&#xff09; 算法解析 3&#xff09; 代码 3 总结 1 另一棵树的子树 leetcode链接…