• jvm类加载器以及双亲委派


    首先来了解几个概念:

    类加载:

        概念:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验--转换解析--初始化,最终形成能被java虚拟机直接使用的java类型,就是jvm的类加载机制。

        类加载包含了以下过程:加载--验证--准备--解析--初始化--使用--卸载

     

    类加载器:

        首先,什么是类加载器?

    概念:把类加载阶段中"通过一个类的全限定名来获取描述此类的二进制流"这个动作放到jvm外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块被称为"类加载器"。

    分类:(针对hot spot而言,因为MRP,maxine的虚拟机完全是由java实现)

    站在java虚拟机的角度上讲,只存在两种不同的类加载器。启动类加载器 和 其他类加载器。

        启动类加载器:由c++实现,是虚拟机自身的一部分.

        其他类加载器:由java实现,独立于虚拟机外部,全继承于抽象类java.lang.ClassLoader.

    站在java开发人员的角度上讲  ,分为三种

      *启动类加载器(BootStrap ClassLoader):  前面已经提到,主要加载<JAVA_HOME>/lib目录中 ,或被-Xbootclasspath参数指定路径中的jar包。

      *扩展类加载器(Extension ClassLoader):由sun.misc.Launcher$ExtClassLoader来实现。主要加载<JAVA_HOME>/lib/ext 目录中 ,或被java.ext.dirs系统变量指定路径中所有类库

      *应用程序类加载器(Application ClassLoader):由sun.misc.Launcher$AppClassLoader来实现。由于这个类加载器是ClassLoader中getSystemClassLoader()方法返回值,所以也叫系统类加载器。负责加载用户类路径上(ClassPath)指定的类库,是开发过程中默认的加载器,开发者可直接使用。

    说到这里,不得不提一下"双亲委派模型(Parent Delegation Model)"。如上图。

    双亲委派模型:描述类加载器之间的层次关系的就是双亲委派模型。

    双亲委派模型要求出顶层的 启动类加载器 外,其余类加载器都应有自己的父类加载器。

    加载器之间的父子关系不是靠继承的关系实现,是使用组合关系的关系来复用父类加载器的代码。

    双亲委派模型工作过程:若一个类加载器收到类加载请求,他首先不会自己尝试去加载这个类,而是把这个请求委派给父类加载器去完成,每一层类加载器都是如此,所以所有请求都会传送到顶层的BootStrap ClassLoader,只有当父类加载器反馈自己无法完成这个加载请求(它的搜索范围没找到),子加载器才会自己尝试去加载。

    使用双亲委派模型好处:

    java类以及它的类加载器一起具备了一种带有优先级的层次关系。如 java.lang.Object(它在rt.jar之中)。

        首先我们要知道一点,同一个类 被不同的 类加载器 加载成两个类之后,这两个类是不同的。

    如果java.lang.Object类被不同的类加载器加载很多次,jvm中存在了多个不同的Object类,那么java类型体系中最基础的行为也无从保证,应用程序会一片混乱(we know,all the class extends from java.lang.Object,如果Object存在多个品种,那绝对是灾难)。

        相反,使用了双亲委派模型,无论哪个类加载器去加载,都会委派到BoorStrap ClassLoader进行加载,保证了Object在各个类加载器环境中,都是同一个类。

      再提一点双亲委派模型的工作机制,以类 A 为例,A如果以Application ClassLoader方式来加载,Application ClassLoader委派给Extension ClassLoader,再到BootStrap ClassLoader.

    然而,BootStrap ClassLoader管理范围内(<JAVA_HOME>/lib目录中 ,或-Xbootclasspath参数指定路径中的jar包)没查到类A,那么就让最初请求的类加载器,Application ClassLoader来加载

    at last,提一点,双亲委派模型 在jvm成长史上被重大破坏过三次,但是 双亲委派模型确实不错,还是像小强一样的活了下来

  • 相关阅读:
    JVM知识体系
    RabbitMQ学习11死信队列(拒绝消息)
    JUC知识体系
    RabbitMQ学习10死信队列(队列达到最大长度)
    Dropdownlist+objectdatasource设定“请选择”默认选项
    sql DATEPART函数使用
    win7 'IIS APPPOOL\Classic .NET AppPool' 登录失败
    sqlserver2000还原数据库时报设备激活错误的解决方法
    vss和vs2008组合搭建源代码管理器
    在配置win7 IIS浏览网站时 检测到在集成的托管管道模式下不适用的ASP.NET设置 的解决方法
  • 原文地址:https://www.cnblogs.com/xiaoliu66007/p/3376219.html
Copyright © 2020-2023  润新知