Java虚拟机学习笔记(五)——委派模型、ClassLoader

java 双亲委派 Java 中的 双亲委派模型(Parent Delegation Model)是 JVM 类加载机制中的一个重要设计原则。它规定了类加载器如何加载类,并确保类的加载不会因为类路径冲突而导致错误。理解双亲委派模型对于掌握 Java 类加载过程和自定义类加载器非常有帮助。 阅读详情

类加载器

JVM 中内置了三个重要的 ClassLoader,除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承自java.lang.ClassLoader:

类加载器总结

  • BootstrapClassLoader(启动类加载器) :最顶层的加载类,由C++实现,负责加载 %JAVA_HOME%/lib目录下的jar包和类或者或被 -Xbootclasspath参数指定的路径中的所有类。
  • ExtensionClassLoader(扩展类加载器) :主要负责加载目录 %JRE_HOME%/lib/ext 目录下的jar包和类,或被 java.ext.dirs 系统变量所指定的路径下的jar包。
  • AppClassLoader(应用程序类加载器) :面向我们用户的加载器,负责加载当前应用classpath下的所有jar包和类。

双亲委派模型

每一个类都有一个对应它的类加载器。系统中的 ClassLoder 在协同工作的时候会默认使用 双亲委派模型 。即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。加载的时候,首先会把该请求委派该父类加载器的 loadClass() 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 BootstrapClassLoader 中。当父类加载器无法处理时,才由自己来处理。当父类加载器为null时,会使用启动类加载器 BootstrapClassLoader 作为父类加载器。

在这里插入图片描述
每个类加载都有一个父类加载器 。

public class ClassLoaderDemo {
    public static void main(String[] args) {
        System.out.println("ClassLodarDemo's ClassLoader is " + ClassLoaderDemo.class.getClassLoader());
        System.out.println("The Parent of ClassLodarDemo's ClassLoader is " + ClassLoaderDemo.class.getClassLoader().getParent());
        System.out.println("The GrandParent of ClassLodarDemo's ClassLoader is " + ClassLoaderDemo.class.getClassLoader().getParent().getParent());
    }
}
ClassLodarDemo's ClassLoader is sun.misc.Launcher$AppClassLoader@18b4aac2
The Parent of ClassLodarDemo's ClassLoader is sun.misc.Launcher$ExtClassLoader@1b6d3586
The GrandParent of ClassLodarDemo's ClassLoader is null

AppClassLoader的父类加载器为ExtClassLoader ExtClassLoader的父类加载器为null,null并不代表ExtClassLoader没有父类加载器,而是 BootstrapClassLoader 。

双亲委派模型实现源码分析

双亲委派模型的实现代码非常简单,逻辑非常清晰,都集中在 java.lang.ClassLoader 的 loadClass() 中,相关代码如下所示。

private final ClassLoader parent; 
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{
    	synchronized (getClassLoadingLock(name)) {
        // 首先,检查请求的类是否已经被加载过
        Class<?> c = findLoadedClass(name);
        if (c == null) {
            long t0 = System.nanoTime();
            try {
                if (parent != null) {//父加载器不为空,调用父加载器loadClass()方法处理
                    c = parent.loadClass(name, false);
                } else {//父加载器为空,使用启动类加载器 BootstrapClassLoader 加载
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
               //抛出异常说明父类加载器无法完成加载请求
            }
            
            if (c == null) {
                long t1 = System.nanoTime();
                //自己尝试加载
                c = findClass(name);

                // this is the defining class loader; record the stats
                sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                sun.misc.PerfCounter.getFindClasses().increment();
            }
        }
        if (resolve) {
            resolveClass(c);
        }
        return c;
    }
}

双亲委派模型的好处

双亲委派模型保证了Java程序的稳定运行,可以避免类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类),也保证了 Java 的核心 API 不被篡改。如果没有使用双亲委派模型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个称为 java.lang.Object 类的话,那么程序运行的时候,系统就会出现多个不同的 Object 类。

自定义类加载器

除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承自java.lang.ClassLoader。如果我们要自定义自己的类加载器,需要继承 ClassLoader。

public class ClassLoadDemo{

    public static void main(String[] args) throws Exception {

        ClassLoader clazzLoader = new ClassLoader() {
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                try {
                    String clazzName = name.substring(name.lastIndexOf(".") + 1) + ".class";

                    InputStream is = getClass().getResourceAsStream(clazzName);
                    if (is == null) {
                        return super.loadClass(name);
                    }
                    byte[] b = new byte[is.available()];
                    is.read(b);
                    return defineClass(name, b, 0, b.length);
                } catch (IOException e) {
                    throw new ClassNotFoundException(name);
                }
            }
        };

        String currentClass = "com.classloader.ClassLoadDemo";
        Class<?> clazz = clazzLoader.loadClass(currentClass);
        Object obj = clazz.newInstance();

        System.out.println(obj.getClass());
        System.out.println(obj instanceof com.classloader.ClassLoadDemo);
		//class com.classloader.ClassLoadDemo
		//false 即使都是来自同一个Class文件,加载器不同,仍然是两个不同的类,所以返回值是false
    }
}

补充:Android中的ClassLoader

Android 的 Dalvik/ART 虚拟机如同标准 Java 的 JVM 虚拟机一样,也是同样需要加载 class 文件到内存中来使用,但是在 ClassLoader 的加载细节上会有略微的差别。

Android中的dex

Android 应用打包成 apk 文件时,class 文件会被打包成一个或者多个 dex 文件。将一个 apk 文件后缀改成 .zip 格式解压后(也可以直接解压,apk 文件本质是个 zip 文件),里面就有 class.dex 文件,由于 Android 的 64K 问题,使用 MultiDex 就会生成多个 dex 文件。

Android 中的 Dalvik/ART 无法像 JVM 那样 直接 加载 class 文件和 jar 文件中的 class,需要通过 dx 工具来优化转换成 Dalvik byte code 才行,只能通过 dex 或者 包含 dex 的jar、apk 文件来加载 ,因此 Android 中的 ClassLoader 工作就交给了 BaseDexClassLoader 来处理。

BaseDexClassLoader 及其子类

在 Android 开发者官网上的 ClassLoader 的文档说明中我们可以看到,ClassLoader 是个抽象类,其具体实现的子类有 BaseDexClassLoader 和 SecureClassLoader 。

SecureClassLoader 的子类是 URLClassLoader ,其只能用来加载 jar 文件,这在 Android 的 Dalvik/ART 上没法使用的。

BaseDexClassLoader 的子类是 PathClassLoader 和 DexClassLoader 。

PathClassLoader

PathClassLoader 在应用启动时创建,从 data/app/… 安装目录下加载 apk 文件。

public PathClassLoader(String dexPath, ClassLoader parent) {
    super(dexPath, null, null, parent);
}

public PathClassLoader(String dexPath, String libraryPath,
        ClassLoader parent) {
    super(dexPath, null, libraryPath, parent);
}

他有两个构造方法。

  • dexPath : 包含 dex 的 jar 文件或 apk 文件的路径集,多个以文件分隔符分隔,默认是“:”
  • libraryPath : 包含 C/C++ 库的路径集,多个同样以文件分隔符分隔,可以为空

PathClassLoader 里面除了这 2 个构造方法以外就没有其他的代码了,具体的实现都是在 BaseDexClassLoader 里面,其 dexPath 比较受限制,一般是已经安装应用的 apk 文件路径。

在 Android 中,App 安装到手机后,apk 里面的 class.dex 中的 class 均是通过 PathClassLoader 来加载的。

DexClassLoader

A class loader that loads classes from .jar and .apk filescontaining a classes.dex entry. This can be used to execute code notinstalled as part of an application.

对比 PathClassLoader 只能加载已经安装应用的 dex 或 apk 文件,DexClassLoader 则没有此限制,可以从 SD 卡上加载包含 class.dex 的 .jar 和 .apk 文件,这也是插件化和热修复的基础,在不需要安装应用的情况下,完成需要使用的 dex 的加载。

构造方法

public DexClassLoader(String dexPath, String optimizedDirectory,
        String libraryPath, ClassLoader parent) {
    super(dexPath, new File(optimizedDirectory), libraryPath, parent);
}
  • String dexPath : 包含 class.dex 的 apk、jar 文件路径 ,多个用文件分隔符(默认是 :)分隔

  • String optimizedDirectory : 用来缓存优化的 dex 文件的路径,即从 apk 或 jar 文件中提取出来的 dex 文件。该路径不可以为空,且应该是应用私有的,有读写权限的路径(实际上也可以使用外部存储空间,但是这样的话就存在代码注入的风险)。

  • String libraryPath : 存储 C/C++ 库文件的路径集

  • ClassLoader parent : 父类加载器,遵从双亲委托模型

BaseDexClassLoader

PathClassLoader 和 DexClassLoader,这两者都是对 BaseDexClassLoader 的一层简单封装,真正的实现都在 BaseDexClassLoader 内。

BaseDexClassLoader 有个很重要的字段private final DexPathList pathList他继承ClassLoader,findClass()、findResource()均是基于pathList实现的。

 @Override
 protected Class<?> findClass(String name) throws ClassNotFoundException {
     List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
     Class c = pathList.findClass(name, suppressedExceptions);
     ...
     return c;
 }
 @Override
 protected URL findResource(String name) {
     return pathList.findResource(name);
 }
 @Override
 protected Enumeration<URL> findResources(String name) {
     return pathList.findResources(name);
 }
 @Override
 public String findLibrary(String name) {
     return pathList.findLibrary(name);
 }

DexPathList的构造方法和前面介绍的类似,接受之前传进来的包含 dex 的 apk/jar/dex 的路径集、native 库的路径集和缓存优化的 dex 文件的路径

public DexPathList(ClassLoader definingContext, String dexPath,
        String libraryPath, File optimizedDirectory) {
    ...
}

然后调用 makePathElements() 方法生成一个 Element[] dexElements 数组,Element 是 DexPathList 的一个嵌套类,其有以下字段

static class Element {
	private final File dir;
	private final boolean isDirectory;
	private final File zip;
	private final DexFile dexFile;
	private ZipFile zipFile;
	private boolean initialized;
}

makePathElements() 生成 Element 数组的过程

private static Element[] makePathElements(List<File> files, File optimizedDirectory,
                                          List<IOException> suppressedExceptions) {
    List<Element> elements = new ArrayList<>();
    // 遍历所有的包含 dex 的文件
    for (File file : files) {
        File zip = null;
        File dir = new File("");
        DexFile dex = null;
        String path = file.getPath();
        String name = file.getName();
        // 判断是不是 zip 类型
        if (path.contains(zipSeparator)) {
            String split[] = path.split(zipSeparator, 2);
            zip = new File(split[0]);
            dir = new File(split[1]);
        } else if (file.isDirectory()) {
            // 如果是文件夹,则直接添加 Element,这个一般是用来处理 native 库和资源文件
            elements.add(new Element(file, true, null, null));
        } else if (file.isFile()) {
            // 直接是 .dex 文件,而不是 zip/jar 文件(apk 归为 zip),则直接加载 dex 文件
            if (name.endsWith(DEX_SUFFIX)) {
                try {
                    dex = loadDexFile(file, optimizedDirectory);
                } catch (IOException ex) {
                    System.logE("Unable to load dex file: " + file, ex);
                }
            } else {
                // 如果是 zip/jar 文件(apk 归为 zip),则将 file 值赋给 zip 字段,再加载 dex 文件
                zip = file;
                try {
                    dex = loadDexFile(file, optimizedDirectory);
                } catch (IOException suppressed) {
                    suppressedExceptions.add(suppressed);
                }
            }
        } else {
            System.logW("ClassLoader referenced unknown path: " + file);
        }
        if ((zip != null) || (dex != null)) {
            elements.add(new Element(dir, false, zip, dex));
        }
    }
    // list 转为数组
    return elements.toArray(new Element[elements.size()]);
}

loadDexFile() 方法最终会调用 JNI 层的方法来读取 dex 文件。

DexPathList 的 findClass()方法,传入的完整的类名来加载对应的 class:

public Class findClass(String name, List<Throwable> suppressed) {
	// 遍历 dexElements 数组,依次寻找对应的 class,一旦找到就终止遍历
    for (Element element : dexElements) {
        DexFile dex = element.dexFile;
        if (dex != null) {
            Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
            if (clazz != null) {
                return clazz;
            }
        }
    }
    // 抛出异常
    if (dexElementsSuppressedExceptions != null) {
        suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
    }
    return null;
} 

这里有关于热修复实现的一个点,就是将补丁 dex 文件放到 dexElements 数组前面,这样在加载 class 时,优先找到补丁包中的 dex 文件,加载到 class 之后就不再寻找,从而原来的 apk 文件中同名的类就不会再使用,从而达到修复的目的。

BaseDexClassLader 寻找 class 的路线

  • 当传入一个完整的类名,调用 BaseDexClassLader 的 findClass(String name)方法
  • BaseDexClassLader 的 findClass 方法会交给 DexPathList 的findClass(String name, List<Throwable> suppressed方法处理
  • 在 DexPathList 方法的内部,会遍历 dexFile ,通过 DexFile 的 dex.loadClassBinaryName(name, definingContext, suppressed)来完成类的加载
    实际使用

需要注意的是,在项目中使用 BaseDexClassLoader 或者 DexClassLoader 去加载某个 dex 或者 apk 中的 class 时,是无法调用 findClass() 方法的,因为该方法是包访问权限,你需要调用 loadClass(String className) ,该方法其实是 BaseDexClassLoader 的父类 ClassLoader 内实现的:

public Class<?> loadClass(String className) throws ClassNotFoundException {
    return loadClass(className, false);
}

protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
    Class<?> clazz = findLoadedClass(className);
    if (clazz == null) {
        ClassNotFoundException suppressed = null;
        try {
            clazz = parent.loadClass(className, false);
        } catch (ClassNotFoundException e) {
            suppressed = e;
        }
        if (clazz == null) {
            try {
                clazz = findClass(className);
            } catch (ClassNotFoundException e) {
                e.addSuppressed(suppressed);
                throw e;
            }
        }
    }
    return clazz;
}

上面这段代码结合之前提到的双亲委托模型就很好理解了,先查找当前的 ClassLoader 是否已经加载过,如果没有就交给父 ClassLoader 去加载,如果父 ClassLoader 没有找到,才调用当前 ClassLoader 来加载,此时就是调用上面分析的 findClass() 方法了。

农业AI避坑指南:用YOLO11做叶片病害检测时遇到的5个典型问题 本文分享了使用YOLO11模型进行农业叶片病害检测时常见的五个典型问题及解决方案。针对田间多变光照、病害样本不均衡、标注歧义、背景干扰和边缘部署等挑战,提供了包括场景自适应数据增强、解耦训练、软标签与鲁棒损失函数、困难负样本构建以及模型轻量化部署在内的实战经验,旨在帮助开发者提升农业AI项目的落地效果。 阅读详情

相关推荐

Halcon实战:5分钟搞定自定义直线卡尺工具(附完整代码下载)

本文详细介绍了如何使用Halcon快速开发自定义直线卡尺工具,通过交互式ROI绘制、边缘检测和直线拟合三个核心函数,实现高效工业视觉检测。文章包含完整代码下载,帮助开发者在5分钟内掌握这一实用工具的开发技巧,提升直线检测的精度和效率。

perl8的博客 248

java getclassloader_关于getClass(),Object.class,getClassLoader的理解

1、对Class类的理解:Class类包含了类的信息,如构造方法、方法、属性,可用于反射。以下是所有方法2、获取Class类对象的几种方法:Test test = new Test();(1).test.getClass();在运行时确定,所以运行实例才是该类对象。super.getClass()不能获得父类的类对象,仍然是当前类对象。获得父类类对象:test.getClass().getSup...

weixin_39943220的博客 464

tree_sitter多语言解析器配置实战指南

本文是一份详细的Tree-sitter多语言解析器配置实战指南。文章从零开始,手把手指导如何搭建Python环境、安装指定版本的tree-sitter库、下载并编译多种语言的语法规则,最终构建一个统一的解析器库。通过实战代码演示了如何初始化解析器、解析代码并遍历语法树,旨在帮助开发者高效处理多语言代码分析任务,并分享了高级技巧与常见问题排坑经验。

weixin_29245767的博客 267

关于getClass(),Object.class,getClassLoader的理解

1、对Class类的理解:Class类包含了类的信息,如构造方法、方法、属性,可用于反射。以下是所有方法 2、获取Class类对象的几种方法: Test test = new Test(); (1).test.getClass(); 在运行时确定,所以运行实例才是该类对象。super.getClass()不能获得父类的类对象,仍然是当前类对象。 获得父类类对象:te...

MrwanZH的博客 1万+

第七节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入门 - 用户管理(上)

本节的内容是用户管理,后端Python代码的实现。

cuiwin的专栏 778

Arcgis加载在线地图(内涵各种在线地图)

这三个在线地图是最常用的在线地图,其他几个类型的在线地图请自行查看。,加载出在线图层说明连接成功,点击。1、首先打开Arcgis,找到。

爱吃雪糕的小布丁的博客 1万+

类加载器和双亲委派模型

点击关注公众号及时获取笔主最新更新文章,并可免费领取本文档配套的《Java面试突击》以及Java工程师必备学习资源。 回顾一下类加载过程 类加载器总结 双亲委派模型 双亲委派模型介绍 双亲委派模型实现源码分析 双亲委派模型的好处 如果我们不想要双亲委派模型怎么办? 自定义类加载器 推荐 公众号JavaGuide 后台回复关键字“1”,免费获取JavaGuide配套的Java工程师必...

不忘初心,奋勇前行 412

【AVRCP】规范精讲[19]: 媒体属性全解析,让你的蓝牙设备显示完整歌曲信息

AVRCP协议中的媒体属性是蓝牙音频设备传输歌曲元数据的关键,包含标题、艺术家、专辑等32位ID标识的键值对信息。规范要求字符串属性必须使用UTF-8编码,但乱码问题频发(如中文显示异常),主因是设备未遵循编码标准或使用GBK等非规范格式。常见问题包括信息不全(仅显示标题)、封面缺失(因带宽限制或格式不支持)及更新延迟(通知机制未启用)。解决方案包括强制UTF-8编码、优化封面大小(如300x300像素JPEG)、主动请求缺失属性。Android示例代码展示了通过广播接收器解析媒体属性的方法。

byte轻骑兵的技术小窝 1万+

虚拟机的类加载及双亲委派

之前谈到过字节码文件,可以说字节码文件是虚拟机运行程序的基础。但是有了字节码文件就可以开始运行我们的Java程序吗?其实不然,对于从开发人员编写好Java程序到在虚拟机中正在开始运行的过程来说,编译或编写生成字节码文件只是万里长征的第一步,接下来我们将谈谈字节码文件在虚拟机运行程序时是怎样的存在。 本文的主要内容是虚拟机的类加载机制,双亲委派模型以及如何打破双亲委派模型。 一、类加载机制 首先我们...

Earl_yuan的专栏 435

芒果YOLOv7改进04:Loss篇:原创改进损失函数Repulsion:独家首发最新改进Repulsion Loss解决目标遮挡场景下检测,为解决密集人群检测中遮挡设计的损失函数,打造高效检测器涨点

YOLOv7原创改进Repulsion|首发最新改进为解决密集人群检测中遮挡设计的损失函数

包括YOLOv5、YOLOv7、YOLOv8等模型改进 3251

YOLOv13多分支融合机制+SE注意机制 RepVGGBlock_OREPA架构 map提升4.89,召回率提升8.66

本文提出了一种改进的YOLOv13目标检测模型,通过引入RepVGGOREPA模块和重参数化技术,显著提升了模型性能。实验结果表明,采用RepVGGBlock后,mAP提升4.89,召回率提升8.66%。文章详细介绍了模型移植过程,包括创建YOLOv13-REPVGGOREPA配置文件、修改任务处理代码和模块初始化文件,并提供了完整的OREPA模块实现代码。该模块通过多尺度特征融合和SE注意力机制,实现了训练时的丰富表征能力和推理时的高效计算,为YOLO系列模型提供了新的优化思路。

FJN110的博客 2650

【JVM】类加载过程、类加载器和双亲委派机制的原理

JVM学习(四)---类加载过程基本介绍类加载的时机类加载的过程加载验证准备解析初始化卸载类加载器类与类加载器双亲委派模型破坏双亲委派模型 基本介绍 一个类的完整生命周期如下: 类加载的时机 类加载的过程 Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚拟机是如何加载这些 Class 文件呢? 系统加载 Class 类型的文件主要三步:加载->连接->初始化。连接过程又可分...

weixin_44823875的博客 514

学Simulink——基于Simulink的PMSM矢量控制(FOC)从零搭建

《Simulink下PMSM矢量控制(FOC)全流程开发指南》 本教程系统讲解了基于Simulink的永磁同步电机(PMSM)磁场定向控制(FOC)实现方法。主要内容包括:FOC控制原理与双闭环架构设计、Simulink建模全流程(含PMSM本体建模、坐标变换、PI控制器设计等)、关键调试技巧以及工程扩展方向。教程以48V伺服电机为例,详细演示了从Clarke/Park变换到SVPWM生成的完整实现过程,并提供了参数配置建议和常见问题解决方案。通过本教程,读者可掌握FOC系统的核心实现技术,为开发高性能电机

xiaoheshang_123的博客 273

Java双亲委派模型:为什么要双亲委派?如何打破它?破在哪里?

1. 双亲委派就是类加载器之间的层级关系,加载类的过程是一个递归调用的过程,首先一层一层向上委托父类加载器加载,直到到达最顶层启动类加载器,启动类加载器无法加载时,再一层一层向下委托给子类加载器加载。 2. 双亲委派的目的主要是为了保证`java`官方的类库`\lib`和扩展类库`\lib\ext`的加载安全性,不会被开发者覆盖。...

你学废了吗? 2万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Java ClassLoader双亲委派机制

Java ClassLoader 双亲委派机制

26857259 1303

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【Java原理系列】Java中ClassLoader原理用法示例中文源码分析

**类加载器是负责加载类的对象**。ClassLoader类是一个**抽象类**。 给定类的二进制名称,类加载器应该尝试定位或生成构成该类定义的数据。典型的策略是将名称转换为文件名,然后从文件系统中读取该名称的“类文件”。

wang2leee的博客 5万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

一次尝试绕过ClassLoader双亲委派的实验

一、文章来由来阿里玩Java也有一个多月了,一直对Java虚拟机比较感兴趣,而ClassLoader是整个class载入过程中很重要的组件。而classloader有个双亲委派模型,师兄说这个模型不能破坏,于是打赌一试。相信如果问:为什么要双亲委派,可能有人可以侃侃而谈,但是说到为什么要这么分层,为什么要分三层,如何绕过双亲委派模型。。。这就不是那么容易了,这个时候就需要一些专研了。二、classl

This is bill的专属博客 5559

从类加载到双亲委派:深入解析类加载机制与 ClassLoader

该篇博文介绍了类加载时 Class 文件的简要结构及如何通过自带的一些工具、插件观察编译生成的字节码信息,核心在于详细说明了 Class 加载的过程:Loading、Linking、Initializing 阶段,在 Loading 阶段时介绍了很多有意思、有深意的知识点,如加载类时的双亲委派机制、探知 Tomcat 如何打破双亲委派机制的伪代码、如何自定义类加载器以简单|加密的方式去实现加载我们特殊的类,还有意思的分析了 Launcher 核心类中三大类加载器所加载的 jar 包、目录等文件

vnjohn 博主 > 主线分享后端领域业务设计知识、源码思想、架构设计 3943

Java ClassLoader与双亲委派模型

概述 这里要先说明下java中的ClassLoader 和Android中的ClassLoader是有区别的。 Android从5.0开始就采用art虚拟机, 该虚拟机有些类似Java虚拟机, 程序运行过程也需要通过ClassLoader 将目标类加载到内存中。本篇文章先带大家梳理下java的ClassLoader,可以带着问题去看本篇文章,会有更多的收获。 java中的ClassLoader 类加载就是多种类加载器(ClassLoader)来查找和加载Class文件到Java虚拟机中。类加载器就是根据指定

soso密斯密斯的博客 300

ClassLoader的双亲委派机制

java 是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载器; .class 文件检验器; 内置于java虚拟机的安全特性; 安全管理器及java API; 类的加载体系: java 程序中的 .java 文件编译完会生成 .class 文件,而 .class 文件就是通过被称为类加载器的 ClassLoader 加载的,ClassLo...

Java全栈领域/离线地图/微服务 938

Java7虚拟机类加载机制:从ClassLoader源码看双亲委派

Spring Security 认证源码 UsernamePasswordAuthenticationFilter

2501_93740756的博客 449

java ClassLoader源码剖析和双亲委派模型实现

ClassLoader是做什么的? 一个类的生命周期取决于它Class对象的生命周期,经历加载、连接、初始化、使用、和卸载五个阶段。ClassLoader负责将.class文件中的二进制数据加载到内存中,放到jvm的方法区中。 什么是双亲委派模型 一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载

rain_zhao_0102的博客 352

【JAVA笔记——术】Java ClassLoader类加载机制详解

Java ClassLoader三种类加载器WIki : Java_ClassloaderJAVA类加载器实现了一部分 JRE加载JAVA CLASSES到 JVM 的功能。ClssLoader 实现了懒加载,并且使得JVM不必关心加载文件以及所使用的文件系统。 类加载器虽然只用于实现类的加载动作,但它在JAVA程序中所起到的作用远远不限于类加载阶段。对于任意一个类,都需要有由加载它的类加载

Contributor -> Committer 4283

Java虚拟机双亲委派源码简析

什么是类加载器 我们知道,JAVA虚拟机(后文均称之为JVM)在加载类的过程中,需要经过加载,验证,准备,解析,初始化等操作,而最初的加载阶段,便是通过类加载器ClassLoader将class文件加载到内存中的。 JVM中大致有两种类加载器,启动类加载器以及其他加载器。 启动类加载器(Bootstrap ClassLoader):由C++语言实现(针对HotSpot),负责将存放在<J...

MaskMagician的专栏 478

再也不怕面试官问我类加载器了 超详细解析Android/Java之ClassLoader 双亲委派模型及热部署实践

虚拟机设计团队把类加载过程中的<font color=Crimson>通过一个类的全限定名来获取描述此类的二进制字节流</font>这个动作放到JVM外部去实现,以便让应用程序自己决定如何去获取所需的类,实现这个动作的代码模块就是类加载器;简单点说类加载器就是用来加载Class文件的,它负责将Class的字节码数据转换成JVM运行时数据区(内存)的Class对象

Mango先生的博客 2963

什么是双亲委派?Tomcat是如何扩展ClassLoader的?

在JVM中,首次使用某个类时,JVM会把.class文件的二进制子节流加载到内存的方法区,创建对应的Class对象。虚拟机设计团队把类加载阶段中的通过一个类的全限定名来获取描述此类的二进制字节流这个动作交由ClassLoader类来实现。而判断一个Class对象是否相等,需要根据Class对象和ClassLoader类加载器同时判断,在创建Class对象时,会设置对应的ClassLoader类加载...

iloveoverfly的博客 6782
上一篇: Java虚拟机学习笔记(四)——类加载
下一篇: Android——View的事件分发
PdKingLiu
博客等级 码龄9年 89粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值