ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

类加载机制及双亲委派模型

2022-01-09 11:31:18  阅读:168  来源: 互联网

标签:委派 name 虚拟机 双亲 卸载 父类 加载


虚拟机的类加载机制:

虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型(Java字节码);

 

一个类的完整的声明 周期包括以下几个阶段:

加载、连接(验证、准备、解析)、初始化、使用、卸载;

 

类的加载过程

有一篇博客专门介绍过类的加载过程,这里就不再详细展开了,加载大致是通过类的全限定名获取对应类的二进制字节流,然后将静态的存储结构转换为运行时的动态存储结构,生成一个class对象,作为访问这个类的方法的入口;连接过程包括验证、准备、解析;验证就是检查字节码文件是否符合虚拟机的要求,比如是否是cafe babe开头,检查数据流和控制流是否符合规则,是否会危害虚拟机的正常运行,符号引用对应的直接引用是否存在(是否能够正常解析引用关系等等),初始化过程(clinit<>,不是每个类都必须存在,只是当有类静态变量或者静态代码块static时才会有),会按照代码的顺序收集静态变量的赋值语句,进行赋值操作;使用过程不详细赘述;类的卸载,判断类是否可以卸载的条件比较苛刻,而且就算满足了也不一定会卸载,(1)虚拟机堆中不存在这个类的任何实例;(2)对应类的类加载器已经卸载;(3)不存在该类的clazz对象,保证无法在任何地方通过反射访问到该类;

 

 

本篇文章重点梳理以下双亲委派模型和如何才能够破坏双亲委派模型呢?

 

首先何为双亲委派模型呢?

从Java程序员角度来看类加载器,包括三种类型:启动类加载器(Bootstrap ClassLoader),负责加载JAVA_HOME/lib下的基础类;扩展类加载器,负责加载JAVA_HOME/lib/ext下的相关类,系统类加载器(应用程序类加载器),如果没有特殊指定类加载器,一般就是通过系统类加载器进行类的加载的;

 

双亲委派模型:

除了启动类加载器以外,任何类加载器都要有自己的父类加载器,当收到一个类的加载请求的时候,先将类加载请求委托给父类加载器,只有当父类加载器无法完成加载的时候,才会由子类加载器去尝试加载;

需要注意的是,这里类加载器的父子关系是通过组合的形式来实现的,而不是通过继承;

 

 

接下来通过源代码来看一下双亲委派模型的原理:

private final ClassLoader parent;
    
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }
    
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        
        // 类加载需要先获取锁,防止多个线程并发加载类时会有线程不安全的问题
        synchronized (getClassLoadingLock(name)) {
            
            // 看这个类是否已经完成了加载
            Class<?> c = findLoadedClass(name);
            
            if (c == null) {
                try {
                    if (parent != null) { // 如果父类加载器存在且不为空,就先调用父类的LoadClass尝试加载
                        c = parent.loadClass(name, false);
                    } else {
                        // 父类为空证明是启动类加载器,调用启动类加载器进行加载
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // not found exception catch
                }
            }
            
            if (c == null) {
                
                // 如果c仍然是空,说明父类都没有办法完成加载,则自己尝试去加载类
                c = findClass(name);
            }
        }
        
        if (resolve) {
            resolveClass(c);
        }
    }

  

标签:委派,name,虚拟机,双亲,卸载,父类,加载
来源: https://www.cnblogs.com/kerwins-AC/p/15780554.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有