Java类加载的过程原理

2年前 (2022) 程序员胖胖胖虎阿
194 0 0

我们编写好的代码java代码,经过编译编程.class文件,然后类加载器把.class字节码文件加载到JVM中,接下来执行我们的代码,最后将该类卸载出JVM。而类加载到虚拟机——卸载出虚拟机,这整个生命周期总共分为7个步骤。

1、加载 2、验证 3、准备 4、解析 5、 初始化 6、使用 7、卸载。

其中,验证、准备、解析这三个阶段有称为连接阶段

1、加载

是类加载的第一个阶段,就是将需要用到的类对应的.class字节码文件加载到虚拟机内存中,并在方法区生产一个java.lang.Class对象,作为
程序访问这个类的各种数据的访问入口

public class Test {
    public static void main(String[] args) {
        User user = new User();
    }
}

上面的代码,经过编译会生成两个字节码文件Test.class和User.class 。接着会将整个类Test(包含main方法)的这类加载到虚拟机内存中开始执行。
当执行到User user = new User(),发现需要用到User这个类,就会将User.class加载到内存中。
所以:当需要用到哪个类时,就回去加载哪个类。
Java自带的核心类,会在虚拟机启动时就加载,包括main方法的启动类。不过类加载是个很复杂的过程————

2、验证

从字面上就可以看出这是来效验加载进来的.class文件,里面的内容是否符合规范。毕竟.class文件还是可以人为修改,如果不符合规范,虚拟机就
无法执行。所以这一步还是关键,至于如何验证?

1、文件格式验证

检查字节流是否符合class文件格式规范,是否能被当前版本的虚拟机处理
例如:常量池是否有不支持的常量类型、主次版本是否在当前虚拟机处理范围内、

2、元数据验证

对字节码信息进行语义分析,是否符合Java语言规范
例如:是否有父类(除java.lang.Object)、父类是否继承了不允许被继承的类(final修饰类)

3、字节码验证

通过数据流和控制流分析,确定程序语义是否合法
4、

3、准备阶段

准备阶段是,正式为类变量分配内存并且、设置类变量初始值的阶段。这些变量所使用的内存都是在方法区中进行分配。

public class Test {
    public static int value = 10;
}

当需要用到这个类时,会先将这个类加载到内存中,并验证字节码的合法性,验证之后会进行准备工作了
会为这个类中的类变量分配内存空间,就是上面的value变量,并给一个初始值,不过这里要注意:
这个仅包括类变量,不包括实例变量和局部变量等。并且只给一个初始值,int型的初始值是0。所以准备阶段过后 value的值是 0.而不是 10 。
真正赋值为10 是在初始化阶段。
这个一阶段是这个类分配内存空间,先给类分配内存,在给里面的类变量分配内存。

4、解析阶段

是将常量池的符号引用替换为直接引用的过程
解析主要针对类或接口,字段,类方法,接口方法,方法类型,方法句柄,调用点限定符等7类符号引用

5、初始化阶段:

是类加载中核心的一步,还是上面的代码为例。准备阶段我们已经将为value变量分配了内存空间并给了初始值。
现在就是真正给value赋值的时候,把10赋给了value。
如果类中还有静态代码块的话,也在这一阶段执行。
类初始化的时候,如果父类还没有加载和初始化,也会触发父类的加载和初始化

6、类的使用

任何一个类型在使用之前都必须经历过完整的加载、链接和初始化3个类加载步骤。一旦一个类型成功经历过这3个步骤之后,便*“万事俱备,只欠东风”*,就等着开发 者使用了
开发人员可以在程序中文访问和调用它的静态类成员信息(如:静态变量、静态方法),或者使用new关键字为其创建对象实例

7、卸载

emmmmmm也就垃圾回收机制,将一下执行过程

一个类何时结束生命周期,取决于代表它的 Class 对象何时结束生命周期
1、启动类加载器 加载的类型在整个运行期间是不可能 被卸载的(JVM和JSL的规范)
2、被系统类加载器 扩展类加载器的类型在 运行期间 不太可能被卸载。 因为系统类加载器实例 或者扩展类的实例基本在整个运行期间总能直接或间接
的被访问到。

3、

Java中有哪些类加载器

BookStrapClassLoader是ExtClassLoader 的父类加载器,默认负责加载%JAVA_HOME%lib下的包和class文件。
ExtClassLoader是AppClassLoader的父类加载器,负责加载%JAVA_HOME/lib/ext文件夹下的jar包和class类。
AppClassLoader是自定义类加载器的父类加载器,负责加载classpath下的类文件

类加载双亲委派模型---------很容易理解的,不要怕

JVM在加载一个类时,会调用AppClassLoader的loadClass方法来加载这个类,在这个方法中(loaderClass)会先使用ExtClassLoader的loaderClass
来加载类,同样ExtClassLoader的loaderClass方法中会先使用BookstrapClassoader来加载类,如果BookstrapClassoader加载到,直接成功,要是没有,
ExtClassLoader就回自己尝试加载该类,要是还是没有,则会AppClassLoader来加载这个类。
双亲委派是指,JVM加载类时,会委派ExtClassLoader和Bookstrap进行加载,如果没有加载到,则自己加载。

JVM加载class文件的原理机制
Java中的所有类,必须被装载到JVM中才能运行。
这个装载工作是由JVM的类装载器完成的。
类装载器所做的工作实质:是把类文件从硬盘读取到内存中,作用就是在运行时加载类。

版权声明:程序员胖胖胖虎阿 发表于 2022年10月4日 上午11:00。
转载请注明:Java类加载的过程原理 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...