我们都知道,jvm执行的代码,都是通过jvm加载系统加入的。加载系统的第一步是通过ClassLoader加载class二进制信息,jvm规范中并没有规定class的来源类型,这就给jvm的实现这块很大的灵活。可以放在数据库里,可以放在网络的其他地方(以前的applet),zip文件等。现在大多数都是放在zip包里,我们引入其他class都是通过引入zip包的形式。
 
   ClassLoader关系结构如下
          BootStrap ClassLoader
               |
          Extension ClassLoader
               |
          System ClassLoader
               |
          Custom  ClassLoader
 
BootStrap ClassLoader 是由C++编写,虚拟机的一部分,只用来加载核心类。负责加载目录[JAVA_HOME]/bin下的jar,或者被参数 -DXbootclasspath说指定目录的jar,并且是jvm识别的。
 
Extension ClassLoader是java编写的,对应java系统中的ExtClassLoader类,负责加载java里的ext包里的类。
 
System ClassLoader 也是由java编写,对应系统中的AppClassLoader类,负责加载应用中的代码。
 
Custom ClassLoader是自己定义的ClassLoader,同AppClassLoader类,不同的事,他限定了只加载一部分应用中的代码。
 
ClassLoader的双亲委派模型
 
     双亲委派模型,主要是整理java加载的秩序性,限定核心,扩展类的重复加载。
 
    BootStrap ClassLoader  —>  Extension ClassLoader  —> System ClassLoader —> Custom ClassLoader 的父子关系,是由组合关系组成的。加载类时,先请求parent加载器,如果加载成功就返回;否则自己再作加载。这样有个好处是核心jar类或者扩展jar类可以做到唯一性,不会每个ClassLoader都加载他。
 
 protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // 查找class是否被加载
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                   // 先让父加载ClassLoader加载类
                    if (parent != null) { 
                        c = parent.loadClass(name, false);
                    } else {
                       // 启动类ClassLoader加载
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }
 
                // 仍然没加载到,自己去加载
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);
 
                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
 
从方法中,我们看到,ClassLoader先判断类有没有被加载,如果有直接返回;如果没有在请求父ClassLoader,父ClassLoader在递归相同的操作;如果父ClassLoader为null,表面为启动类加载器,换成启动类加载器加载;如果还没加载,在伦到自己加载。
 
从方法的修饰词 protected 可以看出,ClassLoader的双亲模式是不牢靠的,只要自定义的ClassLoader重载这个方法,就可能破坏双亲委派模型。
 

ClassLoader心得的更多相关文章

  1. 金三银四背后,一个 Android 程序员的面试心得

    回顾一下自己这段时间的经历,九月份的时候,公司通知了裁员,我匆匆忙忙地出去面了几家,但最终都没有拿到offer,我感觉今年的寒冬有点冷.到十二月份,公司开始第二波裁员,我决定主动拿赔偿走人.后续的面试 ...

  2. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  3. NoSql数据库使用半年后在设计上面的一些心得

    NoSql数据库这个概念听闻许久了,也陆续看到很多公司和产品都在使用,优缺点似乎都被分析的清清楚楚.但我心里一直存有一个疑惑,它的出现究竟是为了解决什么问题? 这个疑惑非常大,为此我看了很多分析文章, ...

  4. 我的MYSQL学习心得(二) 数据类型宽度

    我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  5. 我的MYSQL学习心得(三) 查看字段长度

    我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  6. 我的MYSQL学习心得(四) 数据类型

    我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(五) 运 ...

  7. 我的MYSQL学习心得(五) 运算符

    我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  8. 我的MYSQL学习心得(六) 函数

    我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  9. 我的MYSQL学习心得(七) 查询

    我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

随机推荐

  1. ERROR 2002 (HY000): Can 't connect to local MySQL server through socket '/tmp/mysql.sock '(2) "

    找不到mysql.sock这个文件 如果在你操作安装提示创建该文件,重启服务器还是提示这个错误可以试一下 mysql -uroot -h 127.0.0.1 -p 应该是可以直接进入 具体处理方法 重 ...

  2. Leetcode刷题5—最大子序和

    一.题目要求 二.题目背景 动态规划(英语:Dynamic programming,简称 DP)是一种在数学.管理科学.计算机科学.经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式 ...

  3. D3学习之坐标系绘制

    坐标轴的绘制我们需要搞清楚以下三个要点: 1).axis函数 2)..call()函数用于组合 3).坐标轴的平移旋转 关于第三点其实就是"transform","tra ...

  4. USACO 1.2 Broken Necklace

    断点是白色的情况在做题的时候完全没有想到呢... 看到了数据才发现这个问题$qwq$ /* ID:Starry21 LANG:C++ TASK:beads */ #include<iostrea ...

  5. JQ scrollTop 无效的场景

    先要设置DOM为显示,然后在设置scrollTop,先后顺序不能调换.

  6. C++命名建议

    如果想要有效的管理一个稍微复杂一点的体系,针对其中事物的一套统一.带层次结构.清晰明了的命名准则就是必不可少而且非常好用的工具. 活跃在生物学.化学.军队.监狱.黑社会.恐怖组织等各个领域内的大量有识 ...

  7. ABC044 Digit Sum

    题目链接 我的思路略复杂,这里介绍一个比较简洁的做法. 对于 $b \le \sqrt{N}$,暴力枚举 $b$.对于 $b > \sqrt{N}$, 注意到在 $b$ 进制下 $N$ 至多有 ...

  8. PAT A1016 Phone Bills (25)

    题目描述 A long-distance telephone company charges its customers by the following rules: Making a long-d ...

  9. django 路由层 伪静态网页 虚拟环境 视图层

    路由层 无名分组 有名分组 反向解析 路由分发 名称空间 伪静态网页 虚拟环境 视图层 JsonResponse FBV与CBV 文件上传 项目urls.py下面 from app01 import ...

  10. springboot自动配置国际化失效分析

    最近在整理springBoot国际化时,发现国际化没有生效,通过报错提示在 MessageTag -> doEndTag处打断点 最后发现messageSource并不是ResourceBund ...