4.jvm类加载器深入解析及重要特性剖析(代码片段)

zhihaospace zhihaospace     2023-04-19     207

关键词:

一.回顾完整的加载过程

1.完整过程

技术图片

2.时序图

技术图片

  • 类的加载最终产品是位于内存中的Class对象

  • Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区的数据结构的接口

二.类加载器

1.有两种类型的类加载器

  • Java虚拟机自带的加载器

    • 根类加载器(Bootstrap):该加载器没有父加载器,它负责加载虚拟机中的核心类库。根类加载器从系统属性sun.boot.class.path所指定的目录中加载类库。类加载器的实现依赖于底层操作系统,属于虚拟机的实现的一部分,它并没有集成java.lang.ClassLoader类。

    • 扩展类加载器(Extension):它的父加载器为根类加载器。它从java.ext.dirs系统属性所指定的目录中加载类库,或者从JDK的安装目录的jrelibext子目录(扩展目录)下加载类库,如果把用户创建的jar文件放在这个目录下,也会自动由扩展类加载器加载,扩展类加载器是纯java类,是java.lang.ClassLoader的子类。

    • 系统应用类加载器(AppClassLoader/System):也称为应用类加载器,它的父加载器为扩展类加载器,它从环境变量classpath或者系统属性java.class.path所指定的目录中加载类,他是用户自定义的类加载器的默认父加载器。系统类加载器时纯java类,是java.lang.ClassLoader的子类。

  • 用户自定义的类加载器

    • java.lang.ClassLoader的子类

    • 用户可以定制类的加载方式

2.类的加载阶段

注:类加载器并不需要等到某个类被“首次主动使用”时再加载它,可以在之前预先加载。

  • JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类才报告错误(LinkageError错误)

  • 如果这个类没有被程序主动使用,那么类加载器也不会报告错误。

3.类的验证阶段

  • 类被加载后,就进入连接阶段。连接阶段就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去。

  • 类的验证内容:

    • 类文件的结构检查

    • 语义检查

    • 字节码验证

    • 二进制兼容性的验证

4.类的准备阶段

  • 在准备阶段,java虚拟机为类的静态变量分配内存,并设置默认的初始值。

  • 例如对于以下Sample类,在准备阶段,将为int类型的静态变量a分配4个字节的内存空间,并且赋予默认值0,为long类型的静态变量b分配8个字节的内存空间,并且赋予默认值0;

 1 public class Sample 
 2     private static int a = 1;
 3     public static long b;
 4     public static long c;
 5 
 6     static 
 7         b = 2;
 8     
 9 
10             

5.类的初始化阶段

  • 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值。

  • 在程序中,静态变量的初始化有两种途径:

    1. 在静态变量的声明处进行初始化;

    2. 在静态代码块中进行初始化。 

  • 类的初始化步骤

    1. 假如这个类还没有被加载和连接,那就先进行加载和连接

    2. 假如类存在直接父类,并且这个父类还没有被初始化,那就先初始化直接父类

    3. 假如类中存在初始化语句,那就依次执行这些初始化语句

注:当java虚拟机初始化一个类时,要求它的所有父类都已经被初始化,但是这条规则不适用于接口。因此,一个父接口并不会因为它的子接口或者实现类的初始化而初始化。只有当程序首次使用特定的接口的静态变量时,才会导致该接口的初始化。

 

 1 public class MyTest5 
 2 
 3     public static void main(String[] args) 
 4         System.out.println(classChild5.c);
 5     
 6 
 7 
 8 
 9 interface interfaceParent5 
10 
11     Thread thread = new Thread() 
12 
13         
14             System.out.println("interfaceParent5");
15         
16     ;
17 
18 
19 
20 class classParent5 
21 
22     static 
23         System.out.println("classParent5");
24     
25 
26 
27 class classChild5 extends classParent5 implements interfaceParent5 
28 
29 
30     public static int c = 6;
31 
32     static 
33         System.out.println("classChild5");
34     
35 
36 
37 
38 /*
39  * 输出:
40  * classParent5
41  * classChild5
42  * 6
43  * */

 

总结:从上面代码执行结果可以看出,classChild5类初始化,classParent5类初始化,interfaceParent5接口没有初始化,子类初始化父类一定初始化但父接口不一定初始化。

 1 public class MyTest5 
 2 
 3     public static void main(String[] args) 
 4         System.out.println(interfaceChild5.i);
 5     
 6 
 7 
 8 
 9 interface interfaceParent5 
10 
11     Thread thread = new Thread() 
12 
13         
14             System.out.println("interfaceParent5");
15         
16     ;
17 
18 
19 
20 class classParent5 
21 
22     static 
23         System.out.println("classParent5");
24     
25 
26 
27 
28 interface interfaceChild5 extends interfaceParent5
29 
30     int[] i = new int[]1,2,3,4,5;
31 
32     classParent5 cp = new classParent5();
33 
34 
35 /*
36  * 输出:
37  * classParent5
38  * [I@1540e19d
39  * */

总结:子接口初始化但是父接口没有初始化,从上面看出使用new关键字的子接口或类一定会被初始化

技术图片

 

技术图片

6.获取类加载器方法

 

技术图片

技术图片

 

 

深入拆解类加载器,这样的姿势你还不懂吗?(代码片段)

本文导读:1、前奏,举个生活中的小栗子2、为何Java类型加载、连接在程序运行期完成?3、一个类在什么情况下才会被加载到JVM中?什么是主动使用、被动使用?代码示例助你透彻理解类初始化的时机。4、类的加载(Loading)内... 查看详情

jvm进阶之类加载器详解(代码片段)

类加载器详解一、类加载器概述1.作用2.分类3.重要性4.命名空间5.特性二、类加载器分类1.基本概述2.引导类加载器3.扩展类加载器4.系统类加载器5.自定义类加载器三、类加载器测试1.获取类加载器方式2.获取类加载器示例四、类加... 查看详情

jvm进阶之类加载器详解(代码片段)

类加载器详解一、类加载器概述1.作用2.分类3.重要性4.命名空间5.特性二、类加载器分类1.基本概述2.引导类加载器3.扩展类加载器4.系统类加载器5.自定义类加载器三、类加载器测试1.获取类加载器方式2.获取类加载器示例四、类加... 查看详情

8类加载器案例剖析(代码片段)

8.1、使用ClassLoader类中的getParent()方法获取父类加载器packagecom.shtec.classLoader;/***使用ClassLoader类中的getParent()方法获取父类加载器*注意:根类加载器是由C++编写的,其对象为null;*@authorsunhao**/publicclassTest04publicstaticvoidmain(String[]args)... 查看详情

jvm的艺术—类加载器篇(代码片段)

...的传递,喜欢就点个赞引言今天我们继续来深入的剖析类加载器的内容。上节课我们讲了类加载器的基本内容,没看过的小伙伴请加关注。今天我们继续。什么是定义类加载器和初始化类加载器?定义类加载器:假设我们的某一... 查看详情

深入理解java虚拟机——类加载机制(代码片段)

文章目录类加载机制类的生命周期类的加载过程1、加载2、验证3、准备4、解析5、初始化类的初始化时机类加载器类与类加载器类加载器分类双亲委派模型工作过程源码分析双亲委派机制的好处类加载机制类的生命周期一个类型... 查看详情

深入理解反射(代码片段)

一、类的加载、连接和初始化这是jvm那块的知识,复习一下,这其实是和反射有关系的。①类加载指的是将类的class文件读入内存,并为之创建一个java.lang.Class对象(类是种定义,但在java里,万物都是对象,即类这种定义也是对... 查看详情

深入理解java虚拟机--虚拟机类加载机制(代码片段)

文章目录1.虚拟机类加载机制说明2.类生命周期2.1类生命周期总述2.2加载2.3验证2.3.1验证的目的2.3.2验证的四个方面2.4准备2.4.1准备的目的2.5解析2.5.1解析的目的2.5.2补充概念2.6初始化2.6.1初始化阶段说明2.6.2<clinit>方法说明2.7卸... 查看详情

《深入理解jvm——类加载器》(代码片段)

JVM深入理解JVM(6)——类加载器 PostedbyCrowonAugust21,2017虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流(即字节码)”这个动作放到Java虚拟机外部去实现,以便让应用程序自... 查看详情

jvm类加载器篇(上)(代码片段)

JVM类加载器篇1.类加载器的剖析2.类加载器的作用3.类加载器的过程图示4.类加载器的过程(加载阶段)5.类加载器的过程(链接阶段)6.类加载器的过程(初始化阶段)7.类加载器的种类1.类加载器的剖析2.类加载器的作用类加载子系统负责... 查看详情

《深入理解java虚拟机》第三版第七章要点总结(代码片段)

本文仅作为复习清单使用类生命周期加载验证准备解析初始化使用卸载常量优化常量传播常量折叠类的加载通过全限定名获取二进制字节流将静态存储结构转化为方法区的运行时数据结构生成Class对象验证过程(可关闭)文件格式... 查看详情

浅谈类加载器与类加载案例解析(代码片段)

...用类型变量,保存在Java栈,而对象本身保存在堆中。类加载器只负责将.class文件加载到内存中,此后JVM将根据这个数据文件封装成对应的数据结构(类对象),虽然类对象也是对象,但是HotSpot虚拟机将其放在了方法区中。 ... 查看详情

深入理解jvm(③)虚拟机的类加载器(双亲委派模型)(代码片段)

前言先解释一下什么是类加载器,通过一个类的全限定名来获取描述该类的二进制字节流,在虚拟机中实现这个动作的代码被称为“类加载器(ClassLoader)”。类与类加载器类加载器虽然只用于实现类的加载动作,但它在Java程序... 查看详情

重点知识学习(4.1)--[jvm概述,类加载机制]

文章目录一:JVM(Java虚拟机)概述二:JVM类加载[classLoader]类加载子系统加载过程之-->加载阶段加载过程之-->链接阶段加载过程之-->初始化阶段类加载器(1)引导类加载器(启动类加载器BootStrapClassLoader)(2)扩展类加载器(ExtensionClassLo... 查看详情

jvm——深入解析原理和运行机制类加载器

      上次我们说了一下jvm中类加载的过程,大概有加载,连接(验证,准备,解析),初始化这么几个步骤,当然要实现这些功能就需要有加载器,今天我们就来说说jvm中的类加载器。一、... 查看详情

用户自定义类加载器及具体实现(代码片段)

用户自定义类加载器在Java的日常应用程序开发中,类的加载几乎是由上节3种类加载器(引导、扩展和系统类加载器)相互配合执行的,在必要时,我们还可以自定义类加载器,来定制类的加载方式。为什... 查看详情

jvm——深入解析原理和运行机制类加载器

      上次我们说了一下jvm中类加载的过程,大概有加载,连接(验证,准备,解析),初始化这么几个步骤,当然要实现这些功能就需要有加载器,今天我们就来说说jvm中的类加载器。一、... 查看详情

hi,运维,你懂java吗--no.4:jvm-概述

...、JVM组成        JVM核心内容一共分为四大块:类加载器,运行时数据区,本地方法库接口,执行引擎    而对运维来说最重要的就是要掌握运行时数据区。2、类加载器        类加载器的作用就是将class... 查看详情