JVM类加载器的种类、方式和特性

Time:2021-03-04 Author:admin

​    在前面的文章说JVM组件的时候,有提到类加载系统。今天,Java培训的小编就来给大家详细说一说,JVM类加载器的种类、方式和特性。

JVM类加载器的种类、方式和特性

   种类

 

   一般分为启动类加载器、扩展类加载器、应用程序类加载器、自定义类加载器。图中的从自定义类加载器到启动类加载器一层一层使用箭头连接,这种箭头并不是继承关系,而是上下级关系。上下级的联系是通过ClassLoader抽象类继承过来的parent属性设置的。

 

   1、启动类加载器(BootstrapClassLoader)(引导类加载器),加载java核心类库(<JAVA_HOME>/jre/lib/rt.jar),无法被java程序直接引用,是用C++编写的,用来加载其他的类加载器(类加载器本质就是类),是所有加载器的父类。

 

   2、拓展类加载器(ExtensionClassLoader),用来加载java的拓展库(<JAVA_HOME>/jre/lib/ext)。

 

   3、系统类加载器(SystemClassLoader)(应用程序类加载器),用来加载类路径下的Java类

 

   4、用户自定义类加载器,继承java.lang.ClassLoader类的方式实现。

 

   官方文档中将类加载器分为引导类加载器和自定义类加载器,这是因为引导类加载器是使用其他语言实现的,而拓展类、系统类、自定义类加载器全部都是通过继承ClassLoader抽象类实现的,所以都统一被划分为自定义类加载器。

JVM类加载器的种类、方式和特性

   装载方式

 

   1、隐式装载:由加载器加载。

 

   2、显式装载:自定义加载,比如使用反射Class.forName(类路径),类加载器ClassLoader.getSystemClassLoader().loadClass("test.A");使用当前进程上下文的使用的类装载Thread.currentThread().getContextClassLoader().loadClass("test.A")。

 

   类加载是动态的,它不会一次性加载所有类然后运行,而是保证程序运行的基础类(核心类库一部分的类)完全加载到JVM中就运行,这是为了节省内存开销。

JVM类加载器的种类、方式和特性

   类加载器的特性

 

   1、全盘负责:当一个Class类被某个类加载器所加载时,该Class所依赖引用的所有Class都会由这个加载器负责载入,除非显式的使用另一个ClassLoader。(当然只是这个加载器负责,并不一定就是由这个加载器加载,这是由于双亲委托机制的作用)

 

   2、缓存机制:当一个Class类加载完毕后,会放入缓存,在其他类需要引用这个类时就会从缓存中直接使用,这也是为什么我们在修改了文件后需要重启服务器才能使修改生效。

 

   3、双亲委托机制:当一个类加载器收到了类加载的请求时,它首先会将这个请求委派给父类,父类不能执行再自己尝试执行,父类如果存在父类,也会委派给父类,这样传到了启动类加载器加载,当启动类加载器不能读取到类时才会传给子类加载器,然后子类加载器再尝试加载。

 

   这样做的好处是可以防止自定义的类篡改核心类库中的代码,同时防止同一个类被重复加载。

 

   4、可见性:子类加载器可以访问父类加载器加载的类型,但是反过来是不允许的。不然,因为缺少必要的隔离,我们就没办法利用类加载器去实现容器的逻辑。