zoukankan      html  css  js  c++  java
  • JVM(四)JVM的双亲委派模型

    1、两种不同的类加载器

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

    2、类加载器双亲委派模型图

      

    3、对4个加载器的理解

      (1)启动类加载器:这个类加载器负责将存放在<JAVA_HOME>lib 目录下的,例如rt.jar包。

      (2)扩展类加载器:这个类加载器由sun.misc.Launcher$ExtClassLoader实现。它负责加载<JAVA_HOME>libext 目录下的。或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可用直接使用扩展类加载器。

      (3)应用程序类加载器:这个类加载器由sun.misc.Launcher$AppClassLoader实现。由于这个类加载器是ClassLoader中的getSystemClassLoader()方法的返回值,所有一般也称它为系统类加载器。它负责加载用户路径(ClassPath)上所指定的类库,开发者可用直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

      (4)自定义类加载器:就是自己自定义的类加载器。

    4、双亲委派模型的实现

    protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException
        {
            synchronized (getClassLoadingLock(name)) {
                // First, check if the class has already been loaded
                // 首先,检查请求的类是否已经被加载过
                Class c = findLoadedClass(name);
                if (c == null) {
                    long t0 = System.nanoTime();
                    try {
                        if (parent != null) {
                            c = parent.loadClass(name, false);
                        } else {
                            c = findBootstrapClassOrNull(name);
                        }
                    } catch (ClassNotFoundException e) {
                        // ClassNotFoundException thrown if class not found
                        // 如果父类加载器抛出ClassNotFoundException 
                        // from the non-null parent class loader
                        // 说明父类加载器无法完成加载请求
                    }
    
                    if (c == null) {
                        // If still not found, then invoke findClass in order
                        // to find the class.
                        // 在父类加载器无法加载的时候,再调用本身的findClass方法进行类加载 
                        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;
            }
        }   

      注意:即使自定义了自己的类加载器,强行用defineClass()方法区加载一个以"java.lang"开头的类也不会成功,如果尝试这样的话,将会收到一个由虚拟机自己抛出的"java.lang.ScurityException:Prohibitted package name:java.lang"异常。

  • 相关阅读:
    WampServer Mysql配置
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 前10名
  • 原文地址:https://www.cnblogs.com/c-xiaohai/p/8393654.html
Copyright © 2011-2022 走看看