JVM加载机制之类加载器分类

  Java应用程序运行大致如下过程:

                

  上图清晰地展示了类加载的作用:Java类(.java)—> 字节码⽂件(.class) —> 字节码⽂件需要被加载到jvm内存当中(这个过程就是⼀个 类加载的过程)。这各过程中就有⼀个⾮常重要的⻆⾊叫做类加载器(ClassLoader)。

  通过vm配置选项可以观察跟踪类加载器的加载过程,具体如下:

            

  添加vm选项:-Xlog:class+load=info或-Xlog:class+load=trace (参考https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html)。运行后控制台:

            

   当然上图只是截取部分跟踪信息。类加载器有⾃⼰的体系,Jvm内置了⼏种类加载器,包括:引导类加载器、扩展类加载器、系统类加载器,他们之间形成⽗⼦关 系,通过 Parent 属性来定义这种关系,最终可以形成树形结构,如下:

            

  通过代码获取实际类加载器:

            

                

  从上两图可知:

    系统类加载器:1)java语言编写,由jdk.internal.loader.ClassLoaders$AppClassLoader实现;

           2)该类加载是程序中默认的类加载器,一般来说,Java应用的类都是由它来完成加载的,它负责加载环境变量classpath或系统属性java.class.path 指定路径下的类库;

           3)派生于 ClassLoader父类加载器为扩展类加载器——即可以通过ClassLoader.getXXX()方法获取。

      自定义类的加载器就是该类加载器:

            

    扩展类加载器:1)java语言编写,由jdk.internal.loader.ClassLoaders$PlatformClassLoader实现;

           2)java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext 子目录(扩展目录)下加载类库。如果用户创建的JAR 放在此目录下,也会自动由扩展类加载器加载;派生于 ClassLoader;

             3)父类加载器为启动/引导类加载器(所以在获取其父类时为null)。

    启动/引导类加载器:1)这个类加载器使用c/c++实现,嵌套再jvm内部;

           2)它用来加载Java的核心类库(JAVA_HOME/jre/lib/rt.jarresource.jar等),用于提供JVM自身需要的类;

             3)并不继承自java.lang.ClassLoader,没有父加载器。

      String等加载器就是引导类加载器:

            

  另外:⽤户可以⾃定义类加载器(参考JVM自定义加类加载器)——在日常的Java开发中,类加载几乎是由三种加载器配合执行的,在必要时我们还可以自定义类加载器,来定制类的加载方式(比如Tomcat自定义的类加载器,能更好地隔离web应用服务器上的不同应用程序)。

  综合上述,类加载器的角色如下:

            

 

posted on 2024-05-07 11:22  池塘里洗澡的鸭子  阅读(14)  评论(0编辑  收藏  举报