【JVM】类加载

    疯狂讲义看了一遍,jvm看了一遍,也算清晰了些。


一、what


    虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。


二、when


     Java语言里,类型的加载、连接和初始化过程都是在程序运行期间完成的。


三、how


    类从被加载到虚拟机内存中开始,到卸载出内存为止,它的声明周期包括:加载、验证、准备、解析、初始化、使用和卸载。发生顺序如下所示:

        

    加载、验证、准备、初始化和卸载的顺序是确定的,类的加载过程按照这种顺序按部就班的开始,解析阶段不一定,它可以在初始化阶段之后再开始,通常会在一个阶段执行的过程中调用、激活另外一个阶段。


(一)加载


这是类加载机制的第一步,主要完成三件事:


    1、通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件)。(获取的方式可以从zip包中读取,最终成为日后jar,ear,war格式的基础;从网络中获取;运行时计算生成,比如动态代理;其他文件生成,比如jsp文件……)

    2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。这里只是转化了数据结构,并未合并数据。(方法区就是用来存放已被加载的类信息,常量,静态变量,编译后的代码的运行时内存区域)

    3、在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。这个Class对象并没有规定是在Java堆内存中,它比较特殊,虽为对象,但存放在方法区中。


(二)连接


    类的加载过程后生成了类的java.lang.Class对象,接着会进入连接阶段,连接阶段负责将类的二进制数据合并入JRE(Java运行时环境)中。类的连接大致分三个阶段:
    1.验证:验证被加载后的类是否有正确的结构,类数据是否会符合虚拟机的要求,确保不会危害虚拟机安全。
    2.准备:为类的静态变量(static filed)在方法区分配内存,并赋默认初值(0值或null值)。如static int a = 100;

     静态变量a就会在准备阶段被赋默认值0。

     对于一般的成员变量是在类实例化时候,随对象一起分配在堆内存中。

     另外,静态常量(static final filed)会在准备阶段赋程序设定的初值,如static final int a = 123;  静态常量a就会在准备阶段被直接赋值为123,对于静态变量,这个操作是在初始化阶段进行的。

3.解析:jvm将常量池内的符号引用替换为直接引用的过程。


(三)初始化


    是类加载的最后一步,到这个阶段,才真正开始执行类中定义的Java程序代码。在准备阶段,变量已经赋过一次系统要求的初始值,这个阶段开始后,根据程序员通过程序制定的主观计划去初始化类变量和其他资源。

Java虚拟机规范中严格规定了有且只有五种情况必须对类进行初始化

     1、使用new字节码指令创建类的实例,或者使用getstatic、putstatic读取或设置一个静态字段的值(放入常量池中的常量除外),或者调用一个静态方法的时候,对应类必须进行过初始化。

     2、通过java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则要首先进行初始化。

     3、当初始化一个类的时候,如果发现其父类没有进行过初始化,则首先触发父类初始化。

     4、当虚拟机启动时,用户需要指定一个主类(包含main()方法的类),虚拟机会首先初始化这个类。

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


     注意:虚拟机规范使用了“有且只有”这个词描述,这五种情况被称为“主动引用”,除了这五种情况,所有其他的类引用方式都不会触发类初始化,被称为“被动引用”。


被动引用:


  (1)静态常量在编译阶段就会被存入调用类的常量池中,不会引用到定义常量的类,这是一个特例,需要特别记忆,不会触发类的初始化

  (2)通过子类引用父类的静态字段,对于父类属于“主动引用”的第一种情况,对于子类,没有符合“主动引用”的情况,故子类不会进行初始化。

  (3)通过数组来引用类,不会触发类的初始化,因为是数组new,而类没有被new,所以没有触发任何“主动引用”条款,属于“被动引用”。


ps:本篇博客内容基本为jvm高级特性与最佳实践这本书,博文作为知识梳理。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值