zoukankan      html  css  js  c++  java
  • JVM类加载

    Java类加载

    • Java类加载需要经历5个阶段分别是加载,验证,准备,解析与初始化。

    • 类的生命周期为加载,连接,初始化,使用,卸载。

      类生命周期

    加载

    • 加载是类加载的第一个阶段,在这个阶段中,会做三件事情
      1. 通过一个类的全限定名获取该类的二进制流。(通过JVM的类加载器)。
      2. 将该二进制流中的静态存储结构转化为方法区的运行时数据结构。
      3. 在内存中生成该类的Class对象,作为访问该类生成方法区静态数据结构的访问入口。

    验证

    • 验证的目的是为了确保Class文件的字节流中的信息不会危害到JVM虚拟机,在该阶段主要完成了4种验证。
      • 文件格式验证:验证字节流是否符合Class文件的规范,如主次版本号是否在当前虚拟机范围内,常量池中的常量是否有不被支持的类型。
      • 元数据验证:对字节码描述信息进行语义分析,如和这个类是否有父类,是否继承了不被继承的类等。
      • 字节码验证:(最复杂)通过验证数据流和控制流的分析,确定程序语义是否正确,主要针对方法体的验证。如:方法中的类型转换是否正确,跳转指针是否正确等。
      • 符号引用验证:在解析阶段发生,确保解析动作能正确执行。

    准备

    • 准备阶段是为了类的静态变量分配内存并将其初始化为默认值,这些内存都将分配在JVM的方法区中。准备阶段不分配类中的实例变量的内存,实例变量将会在对象实例化时随着对象一起分配到JVM的堆中。

    解析

    • 解析阶段主要是完成了符号运用到直接引用的转换动作。解析动作并不一定在初始化动作完成之前,也可能发生在初始化之后。

    初始化

    • 类初始化阶段是类加载过程的最后一步。在前面的类加载过程中,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中定义的java程序代码(字节码)。

    类加载器(class loader)

    • 用来加载 Java 类到 JVM虚拟机中。VM虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成java.lang.Class类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance()方法就可以创建出该类的一个对象。Java字节代码生成方式并不唯一: Java 字节代码可能是通过工具动态生成的,也可能是通过网络下载的。但第二次实例化一个类时,就从对应Class类newInstance(),不用每次都读取.class文件。

    • 系统自带的类加载器分为三种:

      1. 启动类加载器::C++实现,在java里无法获取,负责加载/lib下的类。
      2. 扩展类加载器: Java实现,可以在java里获取,负责加载/lib/ext下的类。
      3. 应用程序类加载器:是与我们接触对多的类加载器,我们写的代码默认就是由它来加载,ClassLoader.getSystemClassLoader返回的就是它。
    • 双亲委派机制工作过程:

      • 如果一个类加载器收到了类加载的请求.它首先不会自己去尝试加载这个类.而是把这个请求委派给父加载器去完成.每个层次的类加载器都是如此.因此所有的加载请求最终都会传送到启动类加载器中.只有父类加载反馈自己无法加载这个请求(它的搜索范围中没有找到所需的类)时.子加载器才会尝试自己去加载。(特殊时候会破坏双亲委派,因为个加载器能加载的类范围不同,不同加载器加载相同类时,加载到的类不一致。)

        双亲委派机制

    类的生命周期

    • 一个java类的完整的生命周期会经历加载、连接、初始化、使用、和卸载五个阶段。前三个阶段与类加载过程相同。

    使用

    • 类的使用包括主动引用和被动引用。
      • 主动引用(会发生类的初始化)
        1. 通过new关键字实例化对象、读取或设置类的静态变量、调用类的静态方法;
        2. 通过反射方式执行以上三种行为;
        3. 初始化子类的时候,会触发父类的初始化;
        4. 作为程序入口直接运行时(也就是直接调用main方法)。
      • 被动引用
        1. 引用父类的静态字段,只会引起父类的初始化,而不会引起子类的初始化。
        2. 定义类数组,不会引起类的初始化。
        3. 引用类的常量,不会引起类的初始化。

    卸载

    • 在类使用完之后,如果满足下面的情况,类就会被卸载。
      1. 该类所有的实例都已经被回收,也就是JVM堆中不存在该类的任何实例;
      2. 加载该类的ClassLoader已经被回收;
      3. 该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。
    • 如果以上三个条件全部满足,JVM就会在方法区垃圾回收的时候对类进行卸载,类的卸载过程是在方法区中清空类信息,java类的整个生命周期就结束了。
  • 相关阅读:
    vue 图片切换动态绑定
    弹窗居中,不会随页面滚动变化,直接固定在屏幕中央
    GC优化策略官篇2
    UI优化策略网格重建
    GC优化策略官篇1
    Graphics优化策略官篇3
    GC优化策略官篇3
    Scripts优化策略官篇2
    UI优化策略高级技巧
    Scripts优化策略官篇1
  • 原文地址:https://www.cnblogs.com/RitualYang/p/12383473.html
Copyright © 2011-2022 走看看