开发者社区> 寒凝雪> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

深入研究Java虚拟机的类加载机制

简介:
+关注继续查看

说到Java虚拟机的类加载机制,很多朋友第一反应想到的应该就是ClassLoader,我也如此,不过ClassLoader其实只是Java虚拟机加载机制中的一部分,最近在看《深入理解Java虚拟机》,对Java虚拟机的类加载机制有了更深入的了解,不吐不快。

  JVM中类的整个生命周期如下:

  加载=》验证=》准备=》解析=》初始化=》使用=》卸载

  使用和卸载这两个步骤不在今天的讨论范围之内,今天我们将着重讨论一下前5个步骤,也就是JVM中类的整个加载机制。

  1、加载

  类的加载阶段,主要是获取定义此类的二进制字节流,并将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构,最后在Java堆中生成一个代表这个类的java.lang.Class对象作为方法区这些数据的访问入口。

  相对于类加载过程的其他阶段,加载阶段是开发期可控性最强的阶段。我们可以通过定制不通的类加载器,也就是ClassLoader来控制二进制字节流的获取方式。

  关于ClassLoader的介绍,请参照 了解ClassLoader

  2、验证

  验证,准备和解析其实都属于连接阶段,而验证就是连接阶段的第一步。这一阶段主要是为了确保Class文件的字节流中包含的信息复合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

  主要验证过程包括:文件格式验证,元数据验证,字节码验证以及符号引用验证。

  3、准备

  准备阶段正式为类变量分配内存并设置初始值。这里的初始值并不是初始化的值,而是数据类型的默认零值。这里提到的类变量是被static修饰的变量,而不是实例变量。

  关于准备阶段为类变量设置零值的唯一例外就是当这个类变量同时也被final修饰,那么在编译时,就会直接为这个常量赋上目标值。

  4、解析

  解析时虚拟机将常量池中的符号引用替换为直接引用的过程。

  5、初始化

  在准备阶段,变量已经赋过一次系统要求的初始值,在初始化阶段,则是根据程序员通过程序的主观计划区初始化类变量和其他资源。

  Java虚拟机规范规定了有4种情况必须立即对类进行初始化(加载,验证,准备必须在此之前完成)

  1)当使用new关键字实例化对象时,当读取或者设置一个类的静态字段(被final修饰的除外)时,以及当调用一个类的静态方法时,如果类未初始化,则需先初始化。

  2)通过反射机制对类进行调用时,如果类未初始化,则需先初始化。

  3)当初始化一个类时,如果其父类未初始化,先初始化父类

  4)用户指定的执行主类(含main方法的那个类)在虚拟机启动时会先被初始化

  除了上面这4种方式,所有引用类的方式都不会触发初始化,称为被动引用。如:通过子类引用父类的静态字段,不会导致子类初始化;通过数组定义来引用类,不会触发此类的初始化;引用类的静态常量不会触发定义常量的类的初始化,因为常量在编译阶段已经被放到常量池中了。

  总结:

  在上述5个过程当中,验证,准备和解析完全由Java虚拟机主导和控制。只要加载阶段和初始化阶段程序员可以进行控制。在加载阶段可以通过实现自定义的ClassLoader来加载类的二进制流,在初始化阶段程序员则可完全按照需求来为类变量赋值。

本文出自seven的测试人生公众号最新内容请见作者的GitHub页:http://qaseven.github.io/

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java虚拟机类加载机制
Java虚拟机类加载机制
2034 0
Java虚拟机类加载机制
Java虚拟机类加载机制
4234 0
混合云HBR云上备份VMware虚拟机
本文主要介绍一种简单且具备成本效益的混合云下的备份解决方案,可以为任何位置的客户虚拟机和数据提供强有力的保护,包括企业数据中心、远程和分支机构以及云上资源。
1469 0
+关注
5851
文章
223
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载