JVM类加载器与双亲委派模型详解

     类加载器,主要负责将字节码文件(.class文件)加载到内存中。

    从Java虚拟机的角度来讲,类加载器主要分为两种,一种是启动类加载器(Bootstrap ClassLoader),这个类加载器由c++实现,它是Java虚拟机的一部分;另一种是所有其他类加载器,它们由Java语言实现,独立于JVM虚拟机外部,并且全部继承自抽象类Java.lang.ClassLoader。

    当然作为Java开发人员,类加载器一般要划分的细一点,绝大部分Java程序都会使用的类加载器主要有一下几种:

        启动类加载器(Bootstrap ClassLoader):这个类加载器负责将<JAVA_HOME>\lib 下的,并且被虚拟机识别的(仅按照文件名识别 如rt.jar,名字不符合的类库即使放在lib目录中也不会被加载)类库加载到虚拟机内存中。启动类加载器无法被Java程序引用。

        扩展类加载器(Extension ClassLoader):这个类加载器由Java 实现,它负责加载<JAVA_HOME>\lib\ext 路径下的类库,开发者可以直接使用该类加载器。

     应用类加载器(Application ClassLoader):这个类加载器由Java实现,由于这个类加载器是ClassLoader中的getSystemClassLoader()方法的返回值,所以一般也称它为系统类加载器。它负责加载用户自己编写的类(ClassPath下的),用户可以使用这个类加载器,如果用户没有自定义过其他的类加载器,那么这个类加载器就是系统默认的类加载器。

    我们的应用程序都是这三个类加载器配合进行加载的,当然还有可能有我们自己定义的类加载器。它们之间的关系如下图:

                                

        这些类加载器的这种层次关系被称为类加载器的双亲委派模型。双亲委派模型要求除了启动类加载外,其他的类加载器都应有自己的父类加载器。

    那到底双亲委派模型的工作过程是怎样的呢?

        如果一个类收到了类加载的请求,它不会马上去加载这个类,而是把这个请求交给父类加载,每个层次的类加载器都是这样,因此最终所有的类加载请求都会走到启动类加载器。只有父类反馈无法完成加载子类才会尝试进行加载。

    双亲委派模型有个显而易见的好处就是,Java类随着它的类加载器有了一个优先级的层次关系,比如放在rt.jar下的java.lang.Object 无论哪个类想加载它都会传递到启动类加载器这里,用户永远无法加载一个自己编写的与rt.jar类库已有重名的类  ,程序的安全性得到了保障。

猜你喜欢

转载自blog.csdn.net/zhang_hongxin/article/details/81047439