zoukankan      html  css  js  c++  java
  • ClassLoader心得

       
          我们都知道,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重载这个方法,就可能破坏双亲委派模型。
     
  • 相关阅读:
    17个Web前端开发工程师必看的国外网站
    CSS 绘制三角形气泡框
    Javascript冒泡事件
    页面文本框的只读属性readonly的设置与使用focus-blur事件方法的区别
    javascript中的类型的准确检测
    认识Console,调试Javascript
    仿美团页面
    EDM开发之四:错误记录
    EDM开发之一:系统概述
    EDM开发之二:SMTP服务器
  • 原文地址:https://www.cnblogs.com/sten/p/5636544.html
Copyright © 2011-2022 走看看