JVM
双亲委派机制
双亲委派机制(Parent Delegation Model)是 Java 类加载器体系结构中的一个核心原则,它规定了类加载器在尝试加载一个类时的行为模式。根据这一机制,当一个类加载器收到类加载请求时,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成。只有当父类加载器无法加载该类(例如,因为该类不在父类加载器的搜索路径中)时,当前类加载器才会尝试自己去加载。
工作流程
启动类加载器(Bootstrap ClassLoader):
这是最顶层的类加载器,负责加载 Java 核心库(如
rt.jar
),它是由本地代码实现的,并且没有父类加载器。
扩展类加载器(Extension ClassLoader):
通常负责加载位于
$JAVA_HOME/lib/ext
目录下的 JAR 文件。它的父类加载器是启动类加载器。
应用程序类加载器(Application ClassLoader 或 System ClassLoader):
负责加载应用程序的类路径(classpath)上的类文件。它是用户自定义类加载器的默认父类加载器,其父类加载器是扩展类加载器。
用户自定义类加载器:
开发者可以根据需要创建自己的类加载器,这些类加载器继承自
java.lang.ClassLoader
类,并指定一个父类加载器(通常是应用程序类加载器)。
加载过程:
当应用程序中的类加载器接到加载类的请求时,它首先会将这个请求委托给父类加载器处理。
父类加载器再将请求继续向上委托,直到最顶层的启动类加载器。
如果父类加载器能够加载该类,则成功返回;否则,请求会一层层地回退到最初发起请求的应用程序类加载器。
如果所有父类加载器都无法加载该类,则最初的应用程序类加载器会尝试自己加载这个类。
双亲委派机制的优点
安全性:确保标准库和扩展库中的类不会被用户自定义的类加载器所替换,从而避免潜在的安全风险。
避免类的重复加载:由于每个类只会被最合适的类加载器加载一次,因此可以减少内存占用并提高性能。
保证类的唯一性:通过统一管理类的加载过程,确保同一个类在 JVM 中只有一个版本存在,这有助于维护类的一致性和稳定性。
示例说明
假设我们有一个名为 com.example.MyClass
的类,并且我们在应用程序中使用 new MyClass()
来创建其实例。此时,应用程序类加载器会首先检查是否已经加载过这个类。如果没有加载过,它会按照双亲委派机制依次询问扩展类加载器和启动类加载器。如果这些父类加载器都不能找到 MyClass
,那么应用程序类加载器就会负责从应用程序的类路径中查找并加载这个类。