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

    2.1类加载

    1.类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中验证、准备、解析这3个部分被统称为连接(Linking),这7个阶段的发生顺序如图所示:

     2.加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班的开始,而解析阶段则不一定:它在某些情况在可以初始化阶段之后再开始,这是为了支持Java语言的运行时绑定(也称为动态绑定或晚期绑定)。

    3.什么情况下需要开始类加载过程的第一个阶段:加载?

    1)遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则组要先触发其初始化。生成这4条指令的最常见Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类静态方法的时候。

    2)使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行初始化,则需要先触发其初始化。

    3)当虚拟机启动时,用户需要制定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。

    4)当使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先触发其初始化。

    5)虚拟机规范中使用了一个很强的限定于:“有且只有”,这5种场景中的行为称为对一个类进行主动引用。除此之外,所有引用类的方式都不会触发初始化,称为被动引用。下面有3个例子说明被动引用:

    被动之一:

     这段代码运行后,只会输出“SuperClass init!”,而不会输出“SubClass init!”。对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类的初始化。置于是否要触发子类的加载和验证,在虚拟机并未明确规定。

    被动之二:

     这段代码运行之后发现并没有输出“SuperClass init!”说明并没有触发类org.fenixsoft.classloading.SuperClass的初始化阶段,而是触发了另外一个名为Lorg.fenixsoft.classloading.SuperClass的类初始化阶段。它是一个有虚拟机自动生成的、直接继承java.lang.Object的子类,创建动作有字节码指令newarray触发。

    被动之三:

     上述代码运行之后,也没有输出“ConstClass init!”,这是因为虽然在Java源码中引用了ConstClass类中的常量HELLOWORLD,但其实在编译阶段通过常量传播优化,已经将此常量的值“hello world”存储到了常量池中,也就是转换为对常量池的引用。

    2.2类加载的过程

    1.“加载”是“类加载”(Class Loading)过程的一个阶段。在加载阶段,虚拟机需要完成以下3件事情:

    1)通过一个类的限定名来获取定义此类的二进制字节流。

    2)将这个字节流所代表的静态存储结构转换为方法区的运行时数据结构。

    3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

    2.对数组类而言,情况不同。数组本身就不需要通过类加载器创建,它是由Java虚拟机直接创建的。但数组类与类加载器仍然有很密切的关系,因为数组类的元素类型最终是要靠类加载器区去创建。

    3.加载过程:

    1)加载阶段完成后,虚拟机外部的二进制字节流就按照虚拟机所需的格式存储在方法区之中,方法区中的数据结构存储格式有虚拟机实现自定义。

    2)然后在内存中实例化一个java.lang.Class类的对象,这个对象将作为程序访问方法区中的这些类型数据的外部接口。

    4.加载阶段和链接阶段的部分内容是交叉进行的,加载阶段没有完成时,连接阶段可能已经开始。

  • 相关阅读:
    Cartographer源码阅读(1):程序入口
    ROS开发与常用命令
    实时Cartographer测试(1)
    Cartographer安装
    ROS安装(2)
    Linux学习和ROS安装(1)
    无法启动程序
    c# 获取端口的连接数,网站的连接数
    SignarL服务器端发送消息给客户端的几种情况
    c#操作IIS之IISHelper
  • 原文地址:https://www.cnblogs.com/aipeicai/p/13387771.html
Copyright © 2011-2022 走看看