JVM工作原理与实战(十):类加载器-Java类加载器

简介: JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了扩展类加载器、通过扩展类加载器去加载用户jar包、应用程序类加载器等内容。

在Java虚拟机(JVM)中,类加载器负责将类的字节码文件加载到内存中,并生成对应的Class对象。类加载器是Java虚拟机中的重要组成部分,其中Java代码实现的类加载器包括扩展类加载器和应用程序类加载器(JDK8及之前的版本)。

image.gif

一、介绍

扩展类加载器和应用程序类加载器是JDK中提供的、使用Java编写的类加载器。它们是sun.misc.Launcher的静态内部类,并继承自URLClassLoader。这两个类加载器具备通过目录或指定jar包将字节码文件加载到内存中的能力。此外,它们还提供了更多的功能和灵活性,以支持Java应用程序的动态类加载需求。

image.gif

ClassLoader 抽象类,定义了类加载器的具体行为模式,通过JNI调用底层的Java虚拟机方 法。
SecureClassLoader 使用证书机制提升类加载的安全性。
URLClassLoader 利用URL获取目录下或者指定的jar包进行加载,获取其字节码数据。

扩展类加载器

Extension

加载Java安装目录/jre/lib/ext下的类文件。

应用程序类加载器

Application

加载classpath下的类文件。

二、扩展类加载器

扩展类加载器(Extension Class Loader)是JDK中提供的一个功能强大的类加载器,它使用Java语言编写,用于加载Java安装目录/jre/lib/ext下的类文件。该加载器继承自Java的URLClassLoader类,具有高度的灵活性和可扩展性,能够根据需要动态地加载和卸载类文件,从而满足Java应用程序的多样化需求。

image.gif

ClassLoader提供了许多方法来动态加载类,如loadClass()、defineClass()等。这些方法允许程序员在运行时动态地加载类的字节码文件,并生成对应的Class对象。

案例:

获取扩展类加载器:

public class ExtClassLoaderDemo {
    public static void main(String[] args){
        ClassLoader classLoader = ScriptEnvironment.class.getClassLoader();
        System.out.println(classLoader);
    }
}

image.gif

运行结果:

image.gif

三、通过扩展类加载器去加载用户jar包

通过将所需的jar包放入/jre/lib/ext目录下和使用参数进行扩展两种方法,开发者可以利用扩展类加载器来加载用户提供的JAR包。在使用时,请根据具体情况选择最适合的方式,并注意避免可能出现的冲突和问题。

1.放入/jre/lib/ext下进行扩展

一种直接的方法是将所需的jar包放入/jre/lib/ext目录下,让扩展类加载器能够加载到这个jar包中的类。尽管这种方法能够使 JAR 包被类加载器加载,但并不推荐。主要原因是这涉及到更改 JDK 安装目录中的内容,可能会引发不可预测的问题,也可能影响到 JDK 的升级。

2.使用参数进行扩展

推荐,使用-Djava.ext.dirs=jar包目录进行扩展。这种方式可以加载用户提供的 JAR 包,但是会覆盖原始目录。所以在Windows上,可以使用分号(;)来分隔多个目录,在MacOS和Linux上,可以使用冒号(:)来分隔多个目录。

案例:

加载jar包(省略用户JAR包打包步骤):

public class Demo2 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.rye.test.Test");
        System.out.println(aClass);
        ClassLoader classLoader = aClass.getClassLoader();
        System.out.println(classLoader);
//        验证没有覆盖原始目录
        ClassLoader loader = ScriptEnvironment.class.getClassLoader();
        System.out.println(loader);
    }
}

image.gif

使用-Djava.ext.dirs=jar包目录进行扩展:

-Djava.ext.dirs=jar包目录

image.gif

-Djava.ext.dirs="D:\Java\jdk1.8.0_201\jre\lib\ext;D:\Test"

image.gif

image.gif

运行结果:

image.gif

四、应用程序类加载器

应用程序类加载器(Application Class Loader)也是JDK中提供的、使用Java编写的类加载器。它的主要任务是加载应用程序的classpath下的类文件。

案例:

获取应用程序类加载器:

public class AppClassLoader {
    public static void main(String[] args) {
        // 该项目创建的Student类
        Student student = new Student();
        ClassLoader classLoader = Student.class.getClassLoader();
        System.out.println(classLoader);
        // maven依赖中的类
        ClassLoader classLoader1 = FileUtils.class.getClassLoader();
        System.out.println(classLoader1);
    }
}

image.gif

运行结果:

image.gif


总结

JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了扩展类加载器、通过扩展类加载器去加载用户jar包、应用程序类加载器等内容,希望对大家有所帮助。

相关文章
|
1月前
|
NoSQL Java Redis
秒杀抢购场景下实战JVM级别锁与分布式锁
在电商系统中,秒杀抢购活动是一种常见的营销手段。它通过设定极低的价格和有限的商品数量,吸引大量用户在特定时间点抢购,从而迅速增加销量、提升品牌曝光度和用户活跃度。然而,这种活动也对系统的性能和稳定性提出了极高的要求。特别是在秒杀开始的瞬间,系统需要处理海量的并发请求,同时确保数据的准确性和一致性。 为了解决这些问题,系统开发者们引入了锁机制。锁机制是一种用于控制对共享资源的并发访问的技术,它能够确保在同一时间只有一个进程或线程能够操作某个资源,从而避免数据不一致或冲突。在秒杀抢购场景下,锁机制显得尤为重要,它能够保证商品库存的扣减操作是原子性的,避免出现超卖或数据不一致的情况。
65 10
|
1月前
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
44 3
|
1月前
|
安全 算法 Java
Java CAS原理和应用场景大揭秘:你掌握了吗?
CAS(Compare and Swap)是一种乐观锁机制,通过硬件指令实现原子操作,确保多线程环境下对共享变量的安全访问。它避免了传统互斥锁的性能开销和线程阻塞问题。CAS操作包含三个步骤:获取期望值、比较当前值与期望值是否相等、若相等则更新为新值。CAS广泛应用于高并发场景,如数据库事务、分布式锁、无锁数据结构等,但需注意ABA问题。Java中常用`java.util.concurrent.atomic`包下的类支持CAS操作。
64 2
|
1月前
|
Java
Java基础却常被忽略:全面讲解this的实战技巧!
本次分享来自于一道Java基础的面试试题,对this的各种妙用进行了深度讲解,并分析了一些关于this的常见面试陷阱,主要包括以下几方面内容: 1.什么是this 2.this的场景化使用案例 3.关于this的误区 4.总结与练习
|
2月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
2月前
|
Java
Java之CountDownLatch原理浅析
本文介绍了Java并发工具类`CountDownLatch`的使用方法、原理及其与`Thread.join()`的区别。`CountDownLatch`通过构造函数接收一个整数参数作为计数器,调用`countDown`方法减少计数,`await`方法会阻塞当前线程,直到计数为零。文章还详细解析了其内部机制,包括初始化、`countDown`和`await`方法的工作原理,并给出了一个游戏加载场景的示例代码。
Java之CountDownLatch原理浅析
|
2月前
|
Java 索引 容器
Java ArrayList扩容的原理
Java 的 `ArrayList` 是基于数组实现的动态集合。初始时,`ArrayList` 底层创建一个空数组 `elementData`,并设置 `size` 为 0。当首次添加元素时,会调用 `grow` 方法将数组扩容至默认容量 10。之后每次添加元素时,如果当前数组已满,则会再次调用 `grow` 方法进行扩容。扩容规则为:首次扩容至 10,后续扩容至原数组长度的 1.5 倍或根据实际需求扩容。例如,当需要一次性添加 100 个元素时,会直接扩容至 110 而不是 15。
Java ArrayList扩容的原理
|
1月前
|
Java 程序员
Java基础却常被忽略:全面讲解this的实战技巧!
小米,29岁程序员,分享Java中`this`关键字的用法。`this`代表当前对象引用,用于区分成员变量与局部变量、构造方法间调用、支持链式调用及作为参数传递。文章还探讨了`this`在静态方法和匿名内部类中的使用误区,并提供了练习题。
46 1
|
2月前
|
Oracle 安全 Java
深入理解Java生态:JDK与JVM的区分与协作
Java作为一种广泛使用的编程语言,其生态中有两个核心组件:JDK(Java Development Kit)和JVM(Java Virtual Machine)。本文将深入探讨这两个组件的区别、联系以及它们在Java开发和运行中的作用。
134 1
|
2月前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
85 7

热门文章

最新文章