【JVM】类加载

类加载阶段

  • Java代码编译完成后,会生成对应的字节码文件 .class,类加载指的就是将编译好的字节码(不仅仅指.class文件中的字节码,任意的字节码流都可以被读取到JVM)读取到JVM的内存中的过程。
  • 可以分为三个阶段:加载、链接、初始化。
  • 链接分为:验证、准备、解析阶段。
    在这里插入图片描述

一、加载

加载阶段是类加载过程的第一个阶段。
在这个阶段,JVM 的主要目的是将字节码从各个位置(网络、磁盘等)转化为二进制字节流加载到内存中。
接着会为这个类在 JVM 的方法区创建一个对应的 Class 对象,这个 Class 对象就是这个类各种数据的访问入口。

二、链接

1、验证
当 JVM 加载完 Class 字节码文件并在方法区创建对应的 Class 对象之后,JVM 便会启动对该字节码流的校验。
只有符合 JVM 字节码规范的文件才能被 JVM 正确执行。
JVM规范校验、代码逻辑校验。
2、准备
当完成字节码文件的校验之后,JVM 便会开始为类变量分配内存并赋默认值。

  • 分配内存:Java 中的变量有「类变量」和「类成员变量」两种类型,「类变量」指的是被 static 修饰的变量,而其他所有类型的变量都属于「类成员变量」。
    在准备阶段,JVM 只会为「类变量」分配内存,而不会为「类成员变量」分配内存。「类成员变量」的内存分配需要等到初始化阶段才开始。
public static int factor = 3;  // 为 factor 属性分配内存
public String website = "fan"; // 准备阶段不会分配内存
public static final int number = 3;  // 分配内存
  • 赋值:分配内存后,为变量赋予 Java 语言中该数据类型的零值,而不是用户代码里初始化的值。
    factor被赋值为0.
    number被赋值位3:一个变量是常量(被 static final 修饰)在准备阶段,属性便会被赋予用户希望的值。
    final 关键字在 Java 中代表不可改变的意思,意思就是说 number 的值一旦赋值就不会在改变了。因此被 final 修饰的类变量在准备阶段就会被赋予想要的值。
    3、解析
    针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符 7 类引用进行解析。这个阶段的主要任务是将其在常量池中的符号引用替换成直接其在内存中的直接引用。

三、初始化

到了初始化阶段,用户定义的 Java 程序代码才真正开始执行。
在这个阶段,JVM 会根据语句执行顺序对类对象进行初始化,一般来说当 JVM 遇到下面 5 种情况的时候会触发初始化:

  • 遇到 new、getstatic、putstatic、invokestatic 这四条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。
    场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(除final修饰场景)、调用一个类的静态方法。
  • 使用 java.lang.reflect 包的方法对类进行反射调用的时候
  • 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
  • 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
  • 当使用 JDK1.7 动态语言支持时

四、使用

五、卸载

类加载器

两个类是否相等的前提条件是这两个类是由同一个类加载器加载的。如果两个类来自同一个Class文件,但是被同一个虚拟机下不同的类加载器加载,那么这两个类必定不相等。

1.类加载器的分类

1)启动类加载器(Bootstrap Class Loader)
2)扩展类加载器(Extension Class Loader)
3)应用程序类加载器(Application Class Loader)
4)自定义类加载器(User Class Loader)

2.双亲委派模型

  • 双亲委派模型:要求除了顶层启动类加载器外,其余的类加载器都应该有自己的父类加载器。而这里类加载器之间的父子关系不是通过继承来实现的,而是通过组合的关系来复用父加载器的代码。
  • 如果一个类加载器收到了类加载的请求,首先不会自己尝试加载这个类,而是把请求委派给父类加载器来完成,每个层次的类加载器都是如此。所有的类加载请求最终都会被传送到最顶层的启动类加载器种,只有当父加载器无法找到这个加载请求的类时,子类加载器才会尝试去完成加载。
  • 因为双亲委派模型具备一种带有优先级的层次关系,使得无论哪个类加载最终都会委派给处于最顶层的启动类加载器进行加载,因此保证了在程序种各个类加载器环境中都能够保证是同一个类,同时也避免了重复加载。

参考:
https://www.cnblogs.com/chanshuyi/p/the_java_class_load_mechamism.html
https://zhangpan.site/2020/12/25/33.jvm-class-load/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值