高级java每日一道面试题-2024年9月07日-JVM篇-说一下类加载的执行过程?
如果有遗漏,评论区告诉我进行补充
面试官: 说一下类加载的执行过程?
我回答:
在Java中,类的加载是一个重要的过程,它是由Java虚拟机(JVM)的类加载器系统负责的。类加载的过程不仅仅包括加载类的字节码到内存中,还包括链接和初始化等步骤。下面我将详细介绍类加载的整个执行过程。
类加载的阶段
类加载过程可以分为三个主要阶段:加载(Loading)、链接(Linking)和初始化(Initialization)。这三个阶段是按照顺序进行的,其中链接阶段又可以细分为验证(Verification)、准备(Preparation)和解析(Resolution)三个子阶段。
加载(Loading)
- 定义:加载是类加载过程的第一步,在这个阶段,JVM需要通过类的全限定名(即包含包名的类名)来找到对应的字节码文件,并将其加载到JVM的内存中。加载过程中,JVM会创建一个代表该类的
java.lang.Class
对象,作为程序访问该类的各种信息的入口。 - 实现:通常由类加载器(ClassLoader)完成,包括根类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和系统类加载器(System ClassLoader)等。
- 加载阶段由类加载器完成,主要任务包括:
- 通过一个类的全限定名(全路径名)来获取定义此类的二进制字节流。
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
- 在Java堆中生成一个代表这个类的
java.lang.Class
对象,作为方法区这些数据的访问入口。
链接(Linking)
连接阶段分为验证(Verification)、准备(Preparation)和解析(Resolution)三个子阶段。
- 验证(Verification):确保被加载的类的正确性,即字节码文件的正确性,以及是否符合JVM规范等。这是为了确保JVM不会因为加载错误的类而破坏JVM的稳定性。
- 文件格式验证:验证字节流是否符合Class文件格式规范。
- 元数据验证:对字节码描述的信息进行语义分析,以确保其描述的信息符合Java语言规范的要求。
- 字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。
- 符号引用验证:确保解析动作能正确执行。
- 准备(Preparation):为类的静态变量分配内存,并设置其初始值(注意,这里不是将变量赋值为代码中指定的值,而是赋予其数据类型的零值,如int为0,对象引用为null等)。
- 解析(Resolution):将类、接口、字段和方法的符号引用替换为直接引用的过程。即把代码中通过类名、方法名等访问类的内容的方式转换为JVM内部的引用地址。将常量池内的符号引用替换为直接引用。符号引用类似于C语言中的“远指针”,而直接引用可以是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。
初始化(Initialization)
- 定义:类初始化阶段是类加载过程的最后一步,主要执行类构造器
<clinit>()
方法的过程。<clinit>()
方法是由编译器自动收集类中所有类变量的赋值动作和静态代码块(static block)中的语句合并产生的。这个阶段才会执行用户定义的初始化操作(即静态初始化块中的代码和静态变量的赋值操作)。 - 特点:
<clinit>()
方法不需要显示调用,并且在多线程环境下被JVM保证只执行一次。 - 初始化阶段是类加载过程的最后一步,也是类加载过程中最复杂的一环。在此阶段,虚拟机会执行类构造器
<clinit>()
方法。<clinit>()
方法由编译器自动收集类中的所有类变量的赋值动作和静态初始化块中的语句合并生成。<clinit>()
方法与类的构造函数不同,它不需要显示地调用父类构造器,虚拟机会保证在子类的<clinit>()
方法执行前,父类的<clinit>()
方法已经被执行完毕。
类加载器
类加载器负责将类加载到JVM中。Java中的类加载器主要有以下几种:
- 启动类加载器(Bootstrap ClassLoader):负责加载
JAVA_HOME/lib
目录中的类库或-Xbootclasspath参数指定的路径中的类库,它是用C++语言实现的,是JVM自身的一部分。 - 扩展类加载器(Extension ClassLoader):负责加载
JAVA_HOME/lib/ext
目录中的类库或-Djava.ext.dirs参数指定的路径中的类库,它是用Java语言实现的,父类加载器为启动类加载器。 - 应用程序类加载器(Application ClassLoader):负责加载用户类路径(ClassPath)所指定的类,它是用Java语言实现的,父类加载器为扩展类加载器。
类加载的时机
类加载的时机是在类首次使用时,即当JVM发现某个类还没有被加载时才去加载它。具体的触发条件包括:
- 创建类的实例;
- 访问或修改类的静态变量;
- 调用类的静态方法;
- 反射(如
Class.forName()
); - 初始化某个类的子类;
- JVM启动时被标明为启动类的类。
双亲委派模型
Java类加载器遵循双亲委派模型(Parent Delegation Model),即如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把请求委托给父类加载器去完成,每一个层次的类加载器都是如此。只有当父类加载器无法完成此加载请求(它的搜索范围中没有找到所需的类)时,子类加载器才会尝试自己去加载。
总结
类加载过程遵循了“加载-连接-初始化”的顺序,其中连接阶段又进一步细分为验证、准备和解析三个子阶段。这一过程确保了Java类能够安全、有序地被加载到JVM中,使得Java程序能够正确地使用这些类。同时,这一机制也支持了Java的动态加载和运行时动态类型创建等高级特性。
相关文章:
高级java每日一道面试题-2024年9月07日-JVM篇-说一下类加载的执行过程?
如果有遗漏,评论区告诉我进行补充 面试官: 说一下类加载的执行过程? 我回答: 在Java中,类的加载是一个重要的过程,它是由Java虚拟机(JVM)的类加载器系统负责的。类加载的过程不仅仅包括加载类的字节码到内存中,还包…...
笔试强训day09
添加逗号 import sysa list(input())[::-1] s "" cnt 0 for v in a:cnt 1s vif cnt%30:s , print(s.rstrip(,)[::-1])跳台阶 import sys import functools functools.cache def dfs(u):if u1 or u2:# print(f"u {u}")return ureturn dfs(u-1)dfs(…...
软件测试中的黑盒测试方法,包括其定义、目的及主要步骤。
黑盒测试(Black Box Testing)是一种软件测试方法,它侧重于软件的功能性需求验证,而不考虑程序内部结构或代码实现细节。这种方法是从最终用户的角度出发,检查系统是否按照规格说明书的要求工作。黑盒测试的主要目的是验…...
Shell脚本计算π的近似值
计算π的公式很多,本文使用“π的莱布尼茨公式”来计算π的近似值,对应的公式如下: http://upload.wikimedia.org/math/9/e/8/9e804b8a1a11e442be93fed1d52205a9.png 由此我们可以得到求解π的公式为:π=4*(1-(1/3)+(1/5)-(1/7)+(1/9)...) 下面是在linux下使用shell脚本命令…...
进程间通信之消息队列
作用 进程间通信 特点 1 、消息队列中的消息是有类型的。 类型 : 自定义的结构体 , 第一个成员必须是 long 型的 . 表示为该消息的类型 如 : typedef struct 结构体名称 { long type; // 消息的正文 char name[50]; char sex[10]; int age; ... } 别名 ; 2 、消息队…...
人生苦短我用Python 5-xlwings自动调整表格
人生苦短我用Python 5-xlwings自动调整表格 前言依赖主要类App类Books类Sheet 类 示例代码 前言 使用pandas库openpyxl库实现了csv与excel文件的互相转换,csv转excel后若数据超出了单元格的宽度,部分数据无法完整显示。需要手动打开Excel文件࿰…...

移动跨平台框架Flutter详细介绍和学习线路分享
Flutter是一款移动应用程序SDK,一份代码可以同时生成iOS和Android两个高性能、高保真的应用程序。 Flutter目标是使开发人员能够交付在不同平台上都感觉自然流畅的高性能应用程序。我们兼容滚动行为、排版、图标等方面的差异。 在全世界,Flutter正在被越…...
线性代数基础:向量、矩阵、张量及其在机器学习中的应用详解
线性代数基础:向量、矩阵、张量及其在机器学习中的应用详解 线性代数基础:向量、矩阵、张量及其在机器学习中的应用详解一、向量 (Vectors)1. 向量的定义2. 向量在机器学习中的应用3. 向量空间 二、矩阵 (Matrices)1. 矩阵的定义2. 矩阵在机器学习中的应…...
Dockerfile中的RUN、CMD、ENTRYPOINT指令区别
RUN在构建过程中在镜像中执行命令。CMD容器创建时的默认命令。(可以被覆盖)ENTRYPOINT容器创建时的主要命令。(不可被覆盖) 指令介绍 1.RUN 在构建过程中在镜像中执行命令,是在 docker build中执行 2.CMD 作用&am…...

css grid布局属性详解
Grid布局 前言一、认识Grid1.1容器和项目1.2行和列1.3单元格和网格线 二、容器属性2.1.grid-template-columns与grid-template-rows属性2.1.1 直接使用长度单位比如px2.1.2 使用百分比 %2.1.3 使用repeat函数2.1.4 按比例划分 fr 关键字2.1.5 自动填充 auto 关键字2.1.6 最大值…...

Tranformer分布式特辑
随着大模型的发展,如何进行分布式训练也成了每位开发者必备的技能。 1. 单机训练 CPU OffloadingGradient Checkpointing 正向传播时,不存储当前节点的中间结果,在反向传播时重新计算,从而起到降低显存占用的作用 Low Precision…...
【Moveit2官方教程】使用 MoveIt Task Constructor (MTC) 框架来定义和执行一个机器人任务
#include <rclcpp/rclcpp.hpp> // ROS 2 的核心库 #include <moveit/planning_scene/planning_scene.h> // MoveIt 规划场景相关的头文件 #include <moveit/planning_scene_interface/planning_scene_interface.h> // MoveIt 规划场景接口 #include <m…...

使用docker配置wordpress
docker的安装 配置docker yum源 sudo yum install -y yum-utils sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo下载最新版本docker sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-…...
JVM字节码
JVM字节码详解 引言 JVM(Java Virtual Machine,Java虚拟机)字节码是一种中间代码,主要用于Java平台上的程序在不同硬件平台上的移植。Java程序通过编译器将源代码编译成字节码,然后通过JVM解释或即时编译(…...
python访问mysql
要在 Python 中访问 MySQL 数据库,通常会使用 mysql-connector-python 或 pymysql 这两个库之一。以下是使用这两个库的基本示例: 使用 mysql-connector-python 安装库: pip install mysql-connector-python示例代码: import mysql.connector# 连接到 M…...

Java工具插件
一、springboot集成mqtt订阅 阿里云MQTT使用教程_复杂的世界311的博客-CSDN博客_阿里云mqtt 阿里云创建MQTT服务 先找到产品与服务,然后选择物联网平台,找到公共实例,创建一个产品。 创建产品 然后在左侧下拉栏找到设备管理,在设备管理下拉栏找到设备,然后添加设备。添加…...

Class3——Esp32|Thonny——网络连接主机-wifi连接(源代码带教程)
废话不多说——直接上配置源码和图片 一.电脑连接到wifi上(不能是5G) 二.网络调试助手信息设置绑定 1.获取电脑wifi信息 2.设置网络调试助手为一致,然后打开,主机地址是上面的192.168.2.149端口自己设置,UDP然后打开…...

特效【生日视频制作】小车汽车黄金色版悍马车身AE模板修改文字软件生成器教程特效素材【AE模板】
生日视频制作教程小车汽车黄金色版悍马车身AE模板修改文字特效广告生成神器素材祝福玩法AE模板工程 怎么如何做的【生日视频制作】小车汽车黄金色版悍马车身AE模板修改文字软件生成器教程特效素材【AE模板】 生日视频制作步骤: 下载AE模板 安装AE软件 把AE模板导入…...

如何利用Java进行快速的足球大小球及亚盘数据处理与分析
在当今信息爆炸的时代,大量的数据产生和积累,对于企业和个人来说,如何高效地处理和分析这些数据成为了一项重要的任务。Java作为一门强大的编程语言,提供了丰富的工具和库,可以帮助我们快速进行数据处理与分析。下面将…...
代码随想录打卡Day29
今天的题目尊嘟好难…除了第三题没看视频,其他的题目都是看了视频才做出来的。二刷等我。 134. 加油站 感觉这道题和之前的53. 最大子序和有点像,最大子序和是一旦当前总和为负数则立即抛弃当前的总和,从下个位置重新开始计算,而…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...