JVM总结(1)

1.什么是双亲委派:

 

 

 先来说说JVM里面有那些类加载器吧:

1.启动类加载器(BootClassLoader)

2.扩展类加载器(ExtClassLoader)

3.应用类加载器(AppClassLoader)

4.自定义类加载器

那么双亲委派是什么:

        应用类加载器判断自己的空间下是否有该类,有则直接返回,没有的话就扩展类加载器,

        扩展类加载器判断自己的空间下是否有该类,有则直接返回,没有的话就启动类加载器,

        启动类加载器判断自己的空间下是否有该类,有则直接返回,再去调用一下应用类加载器的findClass(),没有的话就抛出异常。

 为什么使用双亲委派:为了安全,这是为了保证如果加载的类是一个系统类,那么会优先由启动类加载器或扩展类加载器去加载,保证系统的安全。

这3种类加载器存在父子关系,即应用类加载器的父亲是扩展类加载器,扩展类加载器的父亲是启动类加载器,但是他们并不是继承关系。

当3种类加载器在加载类是,会先委托上层的类加载器进行加载,一直往上,称为向上委派,如果最顶级的父类加载器没有找到该类时,就会抛出异常。

在ClassLoader的抽象类中:

先去自己的类加载器里面查找,如果找不到,如果存在父类加载器,往父类加载器去查找,如果没有父类加载器就是到了启动类加载器查找了,如有即返回,没有的话再去调用一下应用类加载器的findClass(),没有的话就抛出异常。
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 // 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; } }

  

 

 

那么双亲委派的局限性是什么:它只能向上委派。

打破双亲委派:

1.不委派

2.向下委派。

 

posted @ 2020-11-19 17:03  Takey  阅读(109)  评论(0编辑  收藏  举报