JVM类加载器

发布于:2024-05-13 ⋅ 阅读:(111) ⋅ 点赞:(0)

1、什么是类加载器


       类加载器(ClassLoader)是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术。类加载器只参与加载过程中的字节码获取并加载到内存这一部分。

1.1、类加载器的作用

        类加载器(ClassLoader)负责在类加载过程中的字节码获取并加载到内存这一部分。通过加载字节码数据放入内存转换成byte[],接下来调用虚拟机底层方法将byte[]转换成方法区和堆中的数据。

2、类加载器的分类


类加载器分为两类:一类是Java代码中实现的,一类是Java虚拟机底层源码实现的。

类加载器的设计JDK8和8之后的版本差别较大,JDK8及之前的版本中默认的类加载器有如下几种:

2.1、启动类加载器

  • 启动类加载器(Bootstrap ClassLoader)是由Hotspot虚拟机提供的、使用C++编写的类加载器。    
  • 默认加载Java安装目录/jre/lib下的类文件,比如rt.jar, tools.jar,resources.jar等。

如何通过启动类加载器去加载用户jar包?   

  • 放入jre/lib下进行扩展:不推荐,尽可能不要去更改JDK安装目录中的内容,会出现即时放进去由于文件名不匹配的问题也不会正常地被加载。    
  • 使用参数进行扩展:推荐使用-Xbootclasspath/a:jar包目录/jar包名进行扩展。  

2.2、扩展类加载器和应用类加载器

  • 扩展类加载器和应用程序类加载器都是JDK中提供的、使用Java编写的类加载器。
  • 它们的源码都位于sun.misc.Launcher中,是一个静态内部类。继承自URLClassLoader,具备通过目录或者指定jar包将字节码文件加载到内存中。

2.2.1、扩展类加载器

  • 扩展类加载器(Extension Class Loader)是JDK中提供的,使用Java编写的类加载器。    
  • 默认加载Java安装目录/jre/lib/ext下的类文件。

如何通过扩展类加载器去加载用户jar包?  

  • 放入/jre/lib/ext下进行扩展:不推荐,尽可能不要去更改JDK安装目录中的内容。 
  • 使用参数进行扩展 :推荐,使用-Djava.ext.dirs=jar包目录进行扩展,这种方式会覆盖掉原始目录,jar包目录可以写多个,windows下多个目录用分号(;)分隔,macos/linux下用冒号分隔(:),例如:-Djava.ext.dirs="C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext;D:\jvm\jar"

2.2.2、应用类加载器

  • 加载classpath下的类文件

2.3、类加载器的分类总结

  1. 启动类加载器(Bootstrap ClassLoader)加载核心类
  2. 扩展类加载器(Extension ClassLoader)加载扩展类
  3. 应用程序类加载器(Application ClassLoader)加载应用classpath中的类
  4. 自定义类加载器,重写findClass方法。
  5. JDK9及之后扩展类加载器(Extension ClassLoader)变成了平台类加载器(Platform ClassLoader)

3、JDK8之后的类加载器

由于JDK9引入了module的概念,类加载器在设计上发生了很多变化。

  • 启动类加载器使用Java编写,位于jdk.internal.loader.ClassLoaders类中。

         Java中的BootClassLoader继承自BuiltinClassLoader实现从模块中找到要加载的字节码资源文件。启动类加载器依然无法通过java代码获取到,返回的仍然是null,保持了统一。

  • 扩展类加载器被替换成了平台类加载器(Platform Class Loader).

         平台类加载器遵循模块化方式加载字节码文件,所以继承关系从URLClassLoader变成了
BuiltinClassLoader,BuiltinClassLoader实现了从模块中加载字节码文件。平台类加载器的存在更多的是为了与老版本的设计方案兼容,自身没有特殊的逻辑。


网站公告

今日签到

点亮在社区的每一天
去签到