关于java:java开发两年类加载器及其加载过程都搞不明白那你工作可能不保了

34次阅读

共计 3458 个字符,预计需要花费 9 分钟才能阅读完成。

内存构造概述

内存构造简图:

内存构造具体图:

中文:

英文:

在这里集体整顿了一些材料,有须要的敌人能够间接点击支付。

Java 基础知识大全

22 本 Java 架构师外围书籍

从 0 到 1Java 学习路线和材料

1000+ 道 2021 年最新面试题

类加载器与加载过程

类加载器子系统作用

图解:

形容:

  • 类加载器子系统负责从文件系统或者网络中加载 class 文件,class 文件在文件结尾有特定的文件标识。
  • ClassLoader 只负责 class 文件的加载,至于它是否能够运行,则由 ExecutionEngine 决定。
  • 加载的类信息寄存于一块称为办法区的内存空间。除了类的信息外,办法区中还会寄存运行时常量池信息,
  • 可能还包含字符串字面量和数字常量(这部分常量信息是 Class 文件中常量池局部的内存映射)

集体了解:

类加载器 ClassLoader 作用

图解:

形容:

  • class file 存在于本地硬盘上,能够了解为设计师画在纸上的模板,而最终这个模板在执行的时候是要
    加载到 JVM 当中来依据这个文件实例化出 n 个截然不同的实例。
  • class file 加载到 JVM 中,被称为 DNA 元数据模板, 放在办法区。
  • 在.class 文件 ->_JVM -> 最终成为元数据模板, 此过程就要一个运输工具 (类装载器 class Loader),
    表演一个快递员的角色。

集体了解:

类加载过程

图解:

形容:

// 加载:
1. 通过一个类的全限定名获取定义此类的二进制字节流
2.将这个字节流所代表的动态存储构造转化为办法区的运行时数据结构
3.在内存中生成一个代表这个类的 java.lang.class 对象,作为办法区这个类的各种数据的拜访入口
// 链接:- 验证:目标在于确保 class 文件的字节流中蕴含信息合乎以后虚拟机要求,保障被加载类的正确性,不会危害虚拟机本身平安,次要包含四种验证,文件格式验证,元数据验证,字节码验证,符号援用验证。- 筹备:为类变量分配内存并且设置该类变量的默认初始值,即零值;这里不蕴含用 final 润饰的 static,因为 final 在编译的时候就会调配了,筹备阶段会显式初始化; 这里不会为实例变量调配初始化,类变量会调配在办法区中,而实例变量是会随着对象一起调配到 Java 堆中。- 解析:将常量池内的符号援用转换为间接援用的过程;事实上,解析操作往往会随同着 JVM 在执行完初始化之
        后再执行;符号援用就是一组符号来形容所援用的指标。符号援用的字面量模式明确定义在《java 虚
        拟机标准》的 class 文件格式中。间接援用就是间接指向指标的指针、绝对偏移量或一个间接定位到目
        标的句柄;解析动作次要针对类或接口、字段、类办法、接口办法、办法类型等。对应常量池中的
        CONSTANT Class info、CONSTANT Fieldref info、cONSTANT Methodref info 等。// 初始化;

类加载器分类

概述:

JVM 反对两种类型的类加载器,别离为疏导类加载器(BootstrapClassLoader)和自定义类加载器(User-Defined classLoader),从概念上来讲,自定义类加载器个别指的是程序中由开发人员自定义的一类类加载器,然而 Java 虚拟机标准却没有这么定义,而是将所有派生于抽象类 ClassLoader 的类加载器都划分为自定义类加载器。

图解:

形容:

// 虚拟机自带的类加载器:启动类加载器(疏导类加载器,Bootstrap classLoader):1. 这个类加载应用 c /C++ 语言实现的,嵌套在 JVM 外部。2. 它用来加载 Java 的外围库(JAVA_HOME/jre/lib/rt.jar、resources.jar 或 sun.boot.class.path
  门路下的内容),用于提供 JVM 本身须要的类;3. 并不继承自 java.lang.ClassLoader,没有父加载器。4. 加载扩大类和应用程序类加载器,并指定为他们的父类加载器。5. 出于平安思考,Bootstrap 启动类加载器只加载包名为 java、javax、sun 等结尾的类

扩大类加载器(Extension ClassLoader):1. 扩大类加载器(Extension ClassLoader)
2.Java 语言编写,由 sun.misc.Launciler$ExtClassLoader 实现。派生于 classLoader 类
3. 父类加载器为启动类加载器
4. 从 java.ext.dirs 零碎属性所指定的目录中加载类库,或从 JDK 的装置目录的 jre/lib/ext 子目录(扩大
  目录)下加载类库。如果用户创立的 JAR 放在此目录下,也会主动由扩大类加载器加载。应用程序类加载器(零碎类加载器,AppClassLoader):1.java 语言编写,由 sun.misc.Launcher$AppclagsLoader
2. 实现派生于 classLoader 类
3. 父类加载器为扩大类加载器
4. 它负责加载环境变量 classpath 或零碎属性 java.class.path 指定门路下的类库
5. 该类加载是程序中默认的类加载器,一般来说,Java 利用的类都是由它来实现加载
6. 通过 classLoader#getSystemclassLoader ()办法能够获取到该类加载器

// 用户自定义类加载器:在 Java 的日常利用程序开发中,类的加载简直是由上述 3 品种加载器相互配合执行的,在必要时,咱们还能够
自定义类加载器,来定制类的加载形式。用户自定义类加载器实现步骤:
用户自定义类加载器实现步骤:
1. 开发人员能够通过继承抽象类 java.lang.classLoader 类的形式,实现本人的类加载器,以满足一些
  非凡的需要
2. 在 JDK1.2 之前,在自定义类加载器时,总会去继承 classLoader 类并重写 loadclass ()办法,从而实现
  自定义的类加载类,然而在 JDK1.2 之后己不再倡议用户去笼罩 loadclass()办法,而是倡议把自定义的类
  加载逻辑写在 findclass ()办法中
3. 在编写自定义类加载器时,如果没有太过于简单的需要,能够间接继承 URLClassLoader 类,这样就能够
  防止本人去编写 findclass ()办法及其获取字节码流的形式,使自定义类加载器编写更加简洁。

ClassLoader 的应用阐明

概述:

ClassLoader 类,它是一个抽象类,其后所有的类加载器都继承自 ClassLoader(不包含启动类加载器)
图解:


获取 ClassLoader 路径:

  • 形式一: 获取以后类的 ClassLoader -> clazz.getClassLoader ()
  • 形式二: 获取以后线程上下文的 ClassLoader -> Thread.currentThread ().getContextclassLoader ()
  • 形式三: 获取零碎的 ClassLoader -> ClassLoader.getsystemClassLoader()
  • 形式四: 获取调用者的 ClassLoader -> DriverManager.getCallerclassLoader ()

双亲委派机制

概述:

Java 虚拟机对 class 文件采纳的是按需加载的形式,也就是说当须要应用该类时才会将它的 class 文件加载到内存生成 class 对象。而且加载某个类的 class 文件时,Java 虚拟机采纳的是双亲委派模式,即把申请交由父类解决, 它是一种工作委派模式。

图解:

形容:

工作原理:
1)如果一个类加载器收到了类加载申请,它并不会本人先去加载,而是把这个申请委托给父类的加载器去执行;
2)如果父类加载器还存在其父类加载器,则进一步向上委托,顺次递归, 申请最终将达到顶层的启动类加载器;
3)如果父类加载器能够实现类加载工作,就胜利返回,假使父类加载器无奈实现此加载工作,子加载器才会尝试
本人去加载,这就是双亲委派模式。
劣势:
1. 防止类的反复加载
2. 爱护程序平安,避免外围 API 被随便篡改

√自定义类: java.lang.String


其余

判断两个 class 对象是否为同一个类:

  • 类的残缺类名必须统一,包含包名。
  • 加载这个类的 ClassLoader(ClassLoader 实例对象)必须统一。

对类加载器的援用:

JVM 必须晓得一个类型是由启动加载器加载的还是由用户类加载器加载的。如果一个类型是由用户类加载器加载的,那么 JVM 会将这个类加载器的一个援用作为类型信息的一部分保留在办法区中。当解析一个类型到另一个类型的援用的时候,JVM 须要保障这两个类型的类加载器是雷同的。

最初

看到这里感觉文章对你有帮忙的话无妨给小编点个赞,感激反对!

正文完
 0