虚拟机类加载机制

什么是类加载机制

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

    Class文件表示一串二进制的字节流,无论以何种形式存在都可以。

类初始化时机

  • 主动引用
    • 当遇到new等字节码指令时,主要场景包括:使用new关键字实例化对象、读取或者设置静态变量、调用类的静态方法;
    • 对类进行反射调用;
    • 初始化一个类,如果其父类还没有初始化,则先触发其父类的初始化;
    • 当虚拟机启动,用户需要制定一个要执行的主类,虚拟机会先初始化这个主类;
    • 使用JDK1.7的动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例最后的解析结果为 REF_getStatic, REF_putStatic, REF_invokeStatic 的方法句柄,并且这个方法句柄所对应的类没有进行过初始 化,则需要先触发其初始化。
  • 被动引用

类加载生命周期

  • 加载

    主要完成三件事:

    • 通过类的完全限定名获取定义该类的二进制字节流;
    • 将这个字节流代表的静态存储结构转换为方法区的运行时数据结构;
    • 在内存中生成一个Class对象,作为方法区这个类的各种数据的访问入口。

      其中二进制字节流可以从以下方式获取:从ZIP包读取;从网络中获取;运行时计算生成,例如动态代理技术。

  • 验证
    确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

  • 准备
    为类变量分配内存并设置初始值,使用的是方法区的内存。

  • 解析
    将常量池的符号引用替换为直接引用的过程。

  • 初始化
    虚拟机执行类构造器x<clinit>方法的过程。

类与类加载器

类加载器的作用:

  1. 实现类的加载
  2. 比较两个类是否相等,需要类本身相等,并且使用同一个类加载器进行加载。
  • 类加载器分类

    • 启动类加载器:负责加载<JRE_HOME>\lib\rt.jar包下的类库,使用C++实现,是虚拟机自身的部分。
    • 其他类加载器:独立于虚拟机,由Java实现
      • 扩展类加载器:加载<JAVA_HOME>\lib\ext中的类库到内存,开发者可以直接使用。
      • 应用程序加载器:加载classpath上指定的类库,如果没有自己定义过类加载器,一般默认这个就是程序默认的类加载器。
  • 双亲委派机制
    当类加载器收到加载请求时,首先不会自己去尝试加载,而是把请求委派给父类加载器,因此所有的请求都会传送到顶层的启动类加载器,只有当父类加载器无法完成加载请求时,子加载器才会尝试自己加载。

    使用双亲委派机制的好处:1. 使得Java类随着他的类加载器一起有了优先级的层次关系。例如位于rt.jar中的Object类,无论哪个类加载器要加载这个类,最后都会由启动类加载器加载,从而保证了Object类在环境中的唯一性。2. 保证Java程序的稳定运行,实现双亲委派的代码都几种在java.lang.ClassLoader的loadClass( )方法中,先检查类是否加载,如果没有加载,就调用父类加载器的loadClass方法,如果父类加载器为空,就调用启动类加载器;如果父类加载器加载失败,抛出异常之后,再调用自己的findClass方法进行加载。

    如何自定义的类加载器:将自己的类加载器逻辑写到loadClass方法里面的findClass方法中。

  • 破坏双亲委派机制

    • JDBC
      JDBC是Java的标准服务,他的代码由启动类加载器去加载,但是它需要调用由独立厂商实现并部署在classpath中的家口提供者代码,但是启动类加载器不认识这些代码,就使用线程上下文加载器去加载,也就是父类加载器委派子类加载器。

    • Tomcat:保证隔离性;支持jsp的修改

      Tomcat的隔离性:

      1. 每个应用程序的类库都是独立的;
      2. Web容器的类库和程序的类库隔离。

      如果Tomcat使用默认的类加载机制,无法保证隔离性,无法加载两个相同类库的不同版本;jsp文件修改之后因为已经加载了这个类,所以不能重新加载。


参考资料:周志明. 深入理解 Java 虚拟机 [M]. 机械工业出版社, 2011.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值