写点什么

java 培训:Java 类加载机制的理解

作者:@零度
  • 2022 年 2 月 28 日
  • 本文字数:1714 字

    阅读完需:约 6 分钟

 谈谈“会”的三个层次

对一门语言的学习,这里谈谈我理解的“会”的三个层次:



第一层:了解这门语言的语法、写法,我把它叫做 hello world 级别;

第二层:了解这门语言的优劣势以及它的生态,了解这门语言的能力范围,我把它叫做 应用 级别;

第三层:了解这门语言的底层运行机制,这有利于对程序进行调优,以及当程序遇到了比较罕见的问题时能够从根上分析解决它。我把它叫做 掌握 级别。

Java 类加载机制

首先我们需要思考一件事,我们编写的 Java 代码,是如何在各种各样的操作系统上运行起来的。



Java 文件通过 Javac 编译成 class 文件,这种中间码被称为字节码。然后由 JVM 加载字节码。这个过程就称为类加载。

运行时,由解释器将字节码解释为一行行的机器码来执行。在程序运行期间,即时编译器会针对热点代码,将该部分字节码编译成机器码以获取更高的执行效率。北京java培训在整个运行时,解释器和即时编译器相互配合,使程序几乎能达到和编译型语言几乎一样的执行速度。这个部分交给专业的编译器开发人员来做,咱们本篇不做深入讲解。

到此上面那张图就讲完了,不要问我右上角那两个表情是怎么回事。就是发现编辑的时候竟然可以添加表情,觉得好玩就试试看。

类的生命周期

在详细讲解之前,我们明确一下类加载流程的目的。站在高处去看,就是把一份被 javac 编译过的文件通过加载,生成某种形式的 class 文件的数据结构送进内存。程序可以调用这个数据结构来构造出 Java 对象。这个过程是在运行时进行的,也是 Java 动态拓展性的根基。



上面这张图表现了类的整个生命周期。而类加载呢,只包含了加载、链接和初始化三个阶段。加载只是类加载的第一个环节,两者要注意区分。解析部分是灵活的,它可以在初始化环节之前或者之后进行,实现后期绑定。类加载的其他环节的顺序是不可改变的。

加载

加载是一个读取 class 文件,将其转化为某种静态数据结构而存储在方法区内,并在堆中生成一个便于用户调用的 Java 对象的过程。

这里值得注意的是,这个 Java 文件不一定是本地文件,泛指各种来源的二进制流,比如网络、数据库或者比如动态代理技术这样的即时生成的 class 文件。

验证

验证的步骤很多,上面的图画得不完全准确。对文件格式的校验其实是发生在加载阶段的。通过才能顺利加载。顺利加载并不代表 JVM 完全认可了这个类,还要进行语法和语义上的分析,保证这个类不会危害 JVM,这是对元数据和字节码上的验证。在解析阶段,还会进行符号引用的验证。随着 JVM 版本的升高,验证过程也在被不断丰富。

准备

准备就是为静态变量赋初始值,注意这里的初始值是 JVM 默认初始值,是固定的,不是咱们写代码时的那个初始值。这里有个比较容易混淆的概念。

Java 内存规范定义了方法区这种抽象概念。主流的 JVM 实现如 HotSpot 在 JDK8 之前使用永久代这种在堆中开辟专门空间的实现方式,JDK8 之后使用元空间这种直接内存取代。

HotSpot 的实现:类的元信息、常量池、静态变量等都存在在 JDK8 之前都存在在永久代这种方法区的具体实现中。JDK8 之后,常量池、静态变量被从方法区移除,转移到了堆中。元信息这些依然保留在方法区,具体的存储方式改成了元空间。

解析

解析是将符号引用替换为直接引用。

静态解析

符号引用就是假如类 A 引用了类 B,加载阶段是静态解析,java培训机构这时候 B 还没有被放到 JVM 内存中,这时候 A 引用的只是代表 B 的符号,这是符号引用。

直接引用就是类 A 在解析阶段发现自己引用了 B,如果这个时候 B 还没被加载。就是直接触发 B 的类加载,之后 B 的符号引用会被替换成实际地址。这被称为直接引用。

动态解析

本文类的生命周期部分引出了后期绑定这个概念。后期绑定其实就是动态解析。如果代码使用了多态。B 是一个抽象类或者接口,A 就不能知道究竟要用哪个来替换,只能等到实际发生调动时在进行实际地址的替换。这就是为什么有的解析发生在初始化之后。

总结

类加载的过程今天就讲这些。咱们来回顾一下类加载的五个阶段。



从 JVM 的角度看,加载的读取二进制流和初始化阶段,是开放了主导权给用户的。用户可以使用动态代理等手段选择是否这个阶段进行加载。还可以使用多态的手段选择是否在这个阶段进行初始化。而剩下的所有部分都是 JVM 内部完成的。

此时你可以闭上眼睛回顾一下类加载的五个阶段,是不是不用死记硬背也能了然于胸了。

文章来源于编程一生

用户头像

@零度

关注

关注尚硅谷,轻松学IT 2021.11.23 加入

还未添加个人简介

评论

发布
暂无评论
java培训:Java类加载机制的理解