欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > JVM类加载器

JVM类加载器

2025/2/24 18:12:38 来源:https://blog.csdn.net/weixin_44581342/article/details/144862574  浏览:    关键词:JVM类加载器

什么是类加载器

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

类加载器的分类

  • 类加载器分为两类,一类是Java代码中实现的,一类是Java虚拟机底层源码实现的。
    • 加载程序运行时的基础类
    • 继承自抽象类ClassLoader
  • JDK8及之前的版本中默认的类加载器有如下几种
    • 启动类加载器Bootstrap-加载Java中最核心的类
    • 扩展类加载器Extension-允许扩展Java中比较通用的类
    • 应用程序类加载器Application- 加载应用使用的类

通过启动类加载器去加载用户jar包:

启动类加载器(BootstrapClassLoader)是由Hotspot虚拟
默认加载Java安装目录/jre/lib下的类文件,比如rt.jar,

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

扩展类加载器Extension

扩展类加载器和应用程序类加载器都是JDK中提供的、使用Java编写的类加载器。

  • 扩展类加载器(Extension Class Loader)是JDK中提供的默认加载Java安装目录/jre/lib/ext下的类文件。
  • 在这里插入图片描述
  • 通过扩展类加载器去加载用户jar包
    • 放入/jre/lib/ext下进行扩展
    • 使用参数进行扩展
      推荐,使用-Djava.ext.dirs=jar包目录进行扩展,这种方式会覆盖掉原始目录,可以用;(windows):(macos/linux)追加上原始目录

应用程序类加载器Application

加载classpath下的类文件(也会加载ext 及启动类加载器不加载的相关 跟双亲委派有关)

Arthas中类加载器相关的功能 查看类加载器加载了什么jar

  • 类加载器的加载路径可以通过classloader–c hash值查看
    可以看到扩展类加载器加载的目录在这里插入图片描述

类加载器的双亲委派机制

双亲委派机制指的是:自底向上查找是否加载过,再由顶向下进行加载。
在这里插入图片描述

双亲委派机制有什么用?

  • 1.保证类加载的安全性
  • 2.避免重复加载

打破双亲委派机制

自定义类加载器

  • 先来分析ClassLoader的原理,ClassLoader中包含了4个核心方法。
  • 双亲委派机制的核心代码就位于loadClass方法中。
  • 正确的去实现一个自定义类加载器的方式是重写findClass方法,这样不会破坏双亲委派机制在这里插入图片描述
  • 双亲委派机制核心代码阅读
//parent等于null说明父类加载器是启动类加载器,直接调用findBootstrapClassOrNull
//否则调用父类加载器的加载方法
protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.long t1 = System.nanoTime();c = findClass(name);// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词