zoukankan      html  css  js  c++  java
  • 虚拟机类加载机制

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

    类加载的时机

    从加载到虚拟机内存中开始,到卸载出内存为止,整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载,其中验证、准备、解析3个部分称为连接。

    加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始(注意是开始,这些阶段通常是相互交叉混合式进行),而解析阶段则不一定:在某些情况下可以在初始化阶段之后在开始,这是为了支持Java语言的运行时绑定。

    类与类加载器

    类加载器虽然只用于实现类的加载动作,但它在Java程序中起到的作用远远不限于类加载阶段。对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间,比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使两个类来源于同一个Class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那两个类就必定是不相等的。

    双亲委派模型

    从虚拟机角度讲,只存在两种不同的类加载器:一种是启动类加载器(Bootstrap ClassLoader),另一种是所有其他的类加载器,这些类加载器都由Java语言实现,独立于虚拟机外部,并且全都继承自抽象类java.lang.ClassLoader。

    从Java开发人员角度来看,类加载器还可以划分得更细致一些。

    启动类加载器(Bootstrap ClassLoader):这个类加载器负责将存放在<JAVA_HOME>lib目录中的,或者被-Xrootclasspath参数所指定的路径中的,并且是虚拟机识别的(仅按照文件名识别,如rt.jar,名字不符合的类库即使放在lib目录下也不会被加载)类库加载到虚拟机内存中。启动类加载器无法被Java程序直接引用,用户在编写自定义类加载器时,如果需要把加载请求委派给引导类加载器,那么直接使用null代替即可。

    扩展类加载器(Extension ClassLoader):这个类加载器负责加载<JAVA_HOME>libext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库。

    应用程序加载器(Application ClassLoader):这个类加载器是ClassLoader中getSystemClassLoader()方法的返回值,所以一般称为系统类加载器,负责加载用户类路径上所指定的类库。

    工作过程:如果一个类加载器收到了类加载的请求,它首先不会自己尝试去加载这个类,而是把这个请求委派给父类加载器去完成,每一层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父类加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。

    好处是:Java类随着它的类加载器一起具备了一种带有优先级的层次关系,例如类java.lang.Object,它存放在rt.jar中,无论哪一个类加载器去加载这个类,最终都是委派给处于模型最顶端的启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都是同一个类。实现简单,代码集中在java.lang.ClassLoader的loadClass()方法之中先检查是否被加载过,若没有加载则调用父加载器的loadClass()方法,若父类加载器为空则默认使用启动类加载器作为父加载器,如果父类加载失败,抛出ClassNotFoundException异常后,再调用自己的findClass()方法进行加载。

    破坏双亲委派模型

    JNDI服务的代码由启动类加载器去加载,但JNDI的目的是对资源进行集中管理和查找,需要调用由独立厂商实现并部署在应用程序的ClassPath下的JNDI接口的提供者的代码,但启动类加载器不知道这些代码,为了解决这个问题,提供线程上下文类加载器,这个类加载器可以通过java.lang.Thread类的setContextClassLoader()方法进行设置,如果创建线程时还未设置,将从父线程中继承一个,如果在应用程序的全局范围内都没有设置过的话,那么这个类加载器默认就是应用程序类加载器。有了线程上下文类加载器,JNDI服务使用这个线程上下文类加载器去加载所需要的SPI代码,也就是父类加载器请求子类加载器去完成类加载的动作。

  • 相关阅读:
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 3037 Saving Beans【Lucas定理】【模板题】【模板】【组合数取余】
    8.Math 对象
  • 原文地址:https://www.cnblogs.com/13jhzeng/p/5897311.html
Copyright © 2011-2022 走看看