深入理解Java虚拟机 --- 类加载机制

news/2024/11/8 13:27:36/文章来源:https://www.cnblogs.com/ayu0v0/p/18534875

类的生命周期

类的生命周期:加载→验证→准备→解析→初始化→使用→卸载

类加载的时机

关于在什么情况下需要需要开始类加载过程的第一个阶段"加载",虚拟机并没有进行强制约束,这点交给虚拟机的具体实现来自由把握。

但严格规定了有且只有六种情况必须立即对类进行"初始化":

(字节码指令:new、getstatic、putstatic、invokestatic)

1、遇到new关键字实例化对象的时候。

2、读取或设置一个类型的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候。

3、调用一个类型的静态方法的时候。

4、使用java.lang.reflect包的方法对类型进行反射调用的时候。

5、当初始化类的时候时,发现其父类还没有进行初始化,需要先触发父类的初始化。

6、当虚拟机启动时,用户需要指定一个要执行的主类(包括main()),那么就会触发该类的初始化。

类的主动使用和被动使用

主动使用:对类主动进行初始化。在上述六种情况。

被动使用:被动使用不会初始化类,但可能会导致类的加载。

1、通过子类引用访问父类的静态字段,不会造成子类的初始化。

2、使用数组定义引用类,不会触发引用类的初始化。

Tips:创建数组的字节码指令为**newarray**。

3、访问类的静态常量

常量在编译的时候会存入调用类的常量池中,本质上没有直接引用到定义常量的类

类加载的过程

加载

目的:

1、通过一个类的全限定名来获取描述该类的二进制字节流。

2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

3、在内存中生成一个代表该类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

类加载器

设计团队想把类加载阶段中"通过一个类的全限定名来获取描述该类的二进制字节流"放到Java虚拟机外部去做,以便让应用程序自己决定如何去获取所需类

实现这个动作的代码被称为类加载器

作用:加载类。

image.png

引导类加载器

Bootstrap ClassLoader:是用C语言写的,不是ClassLoader的子类。被称为根装载器。它是在Java虚拟机启动后初始化的,它主要负责加载%JAVA_HOME%/jre/lib,-Xbootclasspath参数指定的路径以及%JAVA_HOME%/jre/classes中的类。

Bootstrap ClassLoader只加载包名为java、javax、sun等开头的类。

扩展类加载器

Extension ClassLoader:Bootstrap Loader加载ExtClassLoader,并将ExtClassLoader的父加载器设置为Bootstrap Loader。其是用Java写的。ExtClassLoader主要加载%JAVA_HOME%/jre/lib/ext,此路径下的所有classes目录以及java.ext.dirs系统变量指定的路径中类库。

继承于ClassLoader类。

系统类加载器

Application ClassLoader:Bootstrap Loader加载ExtClassLoader后,就会加载AppClassLoader,并将AppClassLoader的父加载器指定为ExtClassLoader。AppClassLoader主要负责加载classpath所指定的位置的类或者是jar文档,它也是Java程序默认的类加载器。

双亲委派机制

双亲委派机制:指先委托父类装载器去寻找目标类,如果父类装载器寻找不到,再从自己负责的路径下寻找目标类。

双亲委派机制主要在ClassLoader中的loadClass方法中体现。

protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{//用synchronized保证加载时类只加载一个Class类synchronized (getClassLoadingLock(name)) {// 首先,检查请求的类是否已经被加载过了Class<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {//双亲委派机制if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// 如果父类加载器抛出ClassNotFoundException// 说明父类加载器无法完成加载请求}if (c == null) {// 在父类加载器无法加载时// 再调用本身的findClass方法来进行类加载c = findClass(name);}}if (resolve) {resolveClass(c);}return c;}}

双亲委派模型的优点:

  • Java类伴随着它的类加载器一起具备了一种带有优先级的层级关系,通过这种层级关系可以避免类的重复加载。

  • 保护程序安全,防止核心API被篡改。

双亲委派模型的缺点:

  • 顶层的ClassLoader无法访问底层ClassLoader加载的类。

双亲委派模型的破坏:

第一次:还没有出现双亲委派模型之前。

第二次:为了解决顶层ClassLoder无法访问底层ClassLoader加载的类,引入了线程上下文类加载器

线程上下文加载器:通过Thread类的setContextClassLoader()方法设置,如果创建线程时未设置,那么会从父线程中继承,**如果在应用程序的全局范围都没有设置过,默认为应用类加载器**。

第三次:由于用户对于程序动态性的追求导致的。如:代码热替换、模块热部署等。

验证

目的:确保Class文件字节流中包含的信息符合规范,保证不会危害虚拟机的安全。

文件格式校验:

魔数、版本号、常量池

元数据校验:

类是否有父类(除了Object,所以类都有父类)、类是否实现了接口的所有方法

字节码验证:

目的:通过数据流分析和控制流数据分析,确定程序语义是合法的、符合逻辑的。

符号引用验证:

目的:确保解析行为能正常运行

准备

为类中定义的静态变量分配内存并设置类变量初始值的阶段。

解析

解析过程是将Java虚拟机将常量池内的符号引用替换为直接引用

符号引用:用字面量来描述所引用的目标。

直接引用:可以直接指向目标的指针。

初始化

初始化阶段就是执行类构造器()方法的过程。

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

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

相关文章

深入理解Java虚拟机 --- 垃圾标记/收集算法

在开始本章之前,我们得了解一个概念,那就是我们怎么知道这个对象是"垃圾"?所以如何定义垃圾就成为我们第一个需要探讨的重要的点之一。 垃圾标记算法 常见的垃圾标记算法有:引用计数算法和可达性分析算法。 引用计数算法 实现思路 每个对象去额外存储一个引用计数…

深入理解Java虚拟机 --- 垃圾回收器

Serial收集器 HotSpot虚拟机运行在客户端模式下的默认新生代收集器。 类型:单线程串行垃圾回收器 垃圾收集算法:复制算法 作用区域:新生代 特点: 1、只会用单个线程去完成垃圾收集工作,用户线程会STW,直到收集结束。 2、没有线程交互,专心做垃圾收集,获得最高的单线程收…

【补档】玄武550电源怎么样? - 约呼的回答 - 知乎

【补档】玄武550电源怎么样? - 约呼的回答 - 知乎 约呼 一个路过的图吧用户 低预算整机非常推荐,高预算慎选。 低预算整机非常推荐,高预算慎选。 优点不少,缺点也有。 先说优点: 价格上来说便宜大碗,用料不错,部分型号反向虚标,比如550v4其实是按650w规格用料来做的,拆…

打造吸睛开场白:六招教你瞬间抓住客户心弦

开场白是在初次接触客户的头30秒至1分钟时间内,销售人员用以吸引目标客户注意力的简短言辞,通常涵盖前几句关键对话。 为了设计出一个引人入胜的开场白,以下策略值得尝试: 赞美客户赞美是人际交往中的润滑剂,恰当的赞美能迅速引起客户的关注。可以从客户的外观、着装、气质…

MM--项目中遇到的一些问题记录

采购订单: 创建采购订单时,供应商对应的信息记录已失效,但是切换供应商之后价格不会自动更新成0 1.SU01-查看用户对应的采购缺省值2.SPRO-维护采购缺省值 采购订单收货的时候,提示无符合条件的行项目 经打断点发现是由于程序中判断时公司间的内部交易所导致的,根本原因是因为采…

C#代码扫描工具SonarQube安装

前言 安装环境:Windows10+SonarQube 9.9.7 LTA Community Edition+jdk17+PostgreSQL 16.4+SonarScanner for .NET 9.0.1 在安装SonarQube 前需要搭建好jdk环境,这里我用的版本是jdk17,之前用过jdk1.8、jdk11和jdk21都失败了。还需提前安装第三方数据库,我用的是PostgreSQL …

数据结构 --树

定义 树是n(n>=0)个结点的有限集。n=0时,称为空树。在任意一棵树非空树中应满足: (1) 有且仅有一个特定的称为根 (root) 的结点 (2) 当时,其余结点可分为个互不相交的有限集,其中每一个集合本身又是一颗树,并且称为根的子树。 基本概念 结点的度:一个结点拥有的子树的…

人工智能--自然语言处理简介

上一篇:《人工智能模型训练中的数据之美——探索TFRecord》 序言:自然语言处理(NLP)是人工智能中的一种技术,专注于理解基于人类语言的内容。它包含了编程技术,用于创建可以理解语言、分类内容,甚至生成和创作人类语言的新作品的模型。在接下来的几章中,我们将会探讨这…

精选 Top10 开源调度工具,解锁高效工作负裁自动化

在大数据和现代 IT 环境中,任务调度与工作负载自动化(WLA)工具是优化资源利用、提升生产效率的核心驱动力。随着企业对数据分析、实时处理和多地域任务调度需求的增加,这些工具成为关键技术。本文将介绍当前技术发展背景下的Top 10开源任务调度工具,并探讨它们在大数据和工…

五分钟入门双拼!

从零开始学双拼的第一篇:概述‍这是从零开始学双拼的第一篇:概述 双拼的原理 如果你使用全拼,想要完整敲出一个字的读音,需要敲出这个字拼音的每个字母。 虽然简拼能简化一点步骤,但除非是很常见的成语、俗语,否则重码率很高,选词很困难。 有没办法提高效率呢?有的,那…

SVN提交日志模板设置

前言:每次提交时都要手动输入很多固定日志信息,或者在最近中选择信息记录会比较麻烦,通过这个设置可以在每次提交时,自动填充日志信息 设置步骤 1:先进入你想要提交svn自动设置模板时的目录(例如策划同学进入到Table表格提交记录,程序同学进入到代码提交目录,美术同学进…

ubuntu:旧版本配置apt源(ubuntu 21.10)

一,旧版本ubuntu上的apt源不能用了 # apt-get update 忽略:1 http://mirrors.aliyun.com/ubuntu hirsute InRelease 忽略:2 http://mirrors.aliyun.com/ubuntu hirsute-security InRelease 忽略:3 http://mirrors.aliyun.com/ubuntu hirsute-updates InRelease 忽略:4 http://…