06JVM_类加载器

一、类加载器

06JVM_类加载器_第1张图片

以JDK8为例:

①启动类加载器

②扩展类加载器

③应用程序类加载器

④自定义类加载器

06JVM_类加载器_第2张图片

①类加载器具有层级关系,当加载一个类的时候,要看所有的上级有没有加载此类。【双亲委派模式】

②类加载器负责在运行时将Java类动态加载到JVM(Java虚拟机),是JRE(Java运行时环境)的一部分。由于类加载器的存在,JVM无需了解底层文件或文件系统即可运行Java程序。

1.启动类加载器:Bootstrap ClassLoader

①启动类加载器是使用C++实现的,嵌套在JVM内部,因此java程序无法直接访问。getClassLoader()得到null

②启动类加载器用来加载jre和jre/lib目录下的核心库,如 java.lang.*,java.util.* 等

③启动类加载器没有父类加载器

④启动类加载器加载扩展类加载器和应用程序类加载器,成为他的父类加载器

2.扩展类加载器 Extension ClassLoader

①扩展类加载器用于加载JVM扩展目录中的类库,位于JDK安装目录下的jre/lib/ext目录中的jar包或目录。

②扩展类的加载器的父类加载器是启动类加载器。

③Java语言编写,由sun.misc.Launcher$ExtClassLoader实现

3.应用程序类加载器Application Class Loader

①系统类加载器,它负责加载用户0类。

②它会搜索应用程序的类路径(包括用户定义的类路径和系统类路径),并加载类文件。

③是java应用程序默认的类加载器

4.自定义类加载器

当不满足开发时,可以自定义加载器。比如用网络加载Java类,为了保证传输中的安全性,采用了加密操作,那么以上3种加载器就无法加载这个类,这时候就需要自定义加载器。

实现步骤

①继承ClassLoader父类

②遵从双亲委派模式,重写findClass方法

③读取类文件的字节码

④调用父类的defineClass方法加载类

⑤使用者调用该类的加载器loadClass方法

二、类加载机制-双亲委派模式

1.介绍

①JVM对class文件采用按需加载的方式,当需要该类的时候,jvm才会将class文件加载到内存产生class对象。

②在加载类的时候,采用双亲委派机制。把请求交给父类处理的一种任务委派模式

06JVM_类加载器_第3张图片

 

2.工作原理

①如果一个类加载器接收到了类加载请求,它自己不会先去加载,会把这个请求委托给父类加载器去执行。

②如果父类还存在父类加载器,就继续向上委托。一直委托到启动类加载器:Bootstrap ClassLoader

③如果父类加载器可以完成加载任务,就返回成功结果。如果父类加载失败,就由子类自己加载,如果失败抛出ClassNotFoundException异常,这就是双亲委派模式

3.优缺点

优点:

①保证安全性,层级关系代表优先级,也就是所有类的加载,优先给启动类加载器,这样就保证了核心类库类

②避免类的重复加载,如果父类加载器加载过了,子类加载器就没有必要再去加载了,确保一个类的全局唯一性

缺点:

①检查类是否加载的委派过程是单向的,即顶层的ClassLoader 无法访问底层的ClassLoader 所加载的类

②启动类加载器中的类为系统核心类,包括一些重要的系统接口,而在应用类加载器中,为应用类。 按照这种模式, 应用类访问系统类自然是没有问题,但是系统类访问应用类就会出现问题。

 

三、线程上下文类加载器

1. 线程上下文类加载器就是双亲委派模型的破坏者,可以在执行线程中打破双亲委派机制的加载链关系,从而使得程序可以逆向使用类加载器

2.Java提供了很多核心接口的定义,这些接口被称为SPI接口,同时为了方便加载第三方的实现类,SPI提供了一种动态的服务发现机制(约定),只要第三方在编写实现类时,在工程内新建一个META-INF/services/目录并在该目录下创建一个与服务接口名称同名的文件,那么在程序启动的时候,就会根据约定去找到所有符合规范的实现类,然后交给线程上下文类加载器进行加载处理

你可能感兴趣的:(JVM,jvm,java)