自学内容网 自学内容网

JVM(双亲委派)

1.双亲委派

在 Java 中,双薪委派通常是指双亲委派模型,它是 Java 类加载器的一种工作模式,用于确保类加载的安全性和一致性。以下是其相关介绍:

定义与作用

  • 定义:双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。当一个类加载器收到类加载请求时,它首先不会自己去尝试加载这个类,而是把请求委派给父类加载器去完成,每一层的类加载器都是如此,直到顶层的启动类加载器。如果父类加载器无法完成加载任务,子类加载器才会尝试自己去加载。
  • 作用:这种模型可以避免类的重复加载,保证 Java 程序的稳定运行。不同的类加载器负责加载不同范围的类,通过这种层级关系,可以确保类的唯一性和安全性。

实现原理

在 Java 中,类加载器是通过ClassLoader类及其子类来实现的。ClassLoader类中有一个loadClass()方法,它是实现双亲委派模型的关键。以下是简化的代码示例:

public class ClassLoader {
    // 父类加载器
    private ClassLoader parent;

    public Class<?> loadClass(String name) throws ClassNotFoundException {
        // 首先检查是否已经加载过该类
        Class<?> c = findLoadedClass(name);
        if (c == null) {
            try {
                // 如果父类加载器不为空,委托父类加载器加载
                if (parent!= null) {
                    c = parent.loadClass(name);
                } else {
                    // 如果父类加载器为空,说明已经到了顶层的启动类加载器
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
                // 父类加载器无法加载,自己尝试加载
                c = findClass(name);
            }
        }
        return c;
    }

    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // 自定义的类加载逻辑,由具体的类加载器实现
        throw new ClassNotFoundException(name);
    }

    protected final Class<?> findLoadedClass(String name) {
        // 查找已经加载的类,由具体的类加载器实现
        return null;
    }

    private Class<?> findBootstrapClassOrNull(String name) {
        // 查找启动类加载器加载的类,由具体的类加载器实现
        return null;
    }
}

应用场景

  • 系统类的加载:Java 核心类库中的类,如java.lang.Objectjava.util.Date等,都是由启动类加载器或其他系统类加载器按照双亲委派模型进行加载的。这确保了这些核心类的唯一性和安全性,避免了用户自定义的同名类对系统类的干扰。
  • 插件化框架:在一些插件化框架中,需要隔离不同插件之间的类加载,以防止类的冲突和混乱。通过使用自定义的类加载器,并遵循双亲委派模型,可以实现插件之间的类加载隔离,每个插件都有自己独立的类加载空间。
  • 安全控制:双亲委派模型可以防止恶意代码伪装成系统类来执行,因为系统类是由受信任的系统类加载器加载的。如果有恶意代码想要替换系统类,由于双亲委派模型的限制,它无法绕过系统类加载器来加载自己定义的类,从而提高了系统的安全性。

2.双亲委派模型的优势和劣势是什么?

优势

  • 避免类的重复加载:双亲委派模型要求类加载器在收到类加载请求时,先将请求委派给父类加载器。只有当父类加载器无法完成加载任务时,子类加载器才会尝试自己加载。这样可以确保一个类只会被加载一次,避免了类的重复加载,节省了系统资源,提高了类加载的效率。
  • 保证类的安全性:在双亲委派模型中,Java 核心类库中的类(如java.lang.Object等)是由启动类加载器或其他系统类加载器加载的。这些类加载器是受信任的,它们只会加载被认可的系统类。由于系统类加载器的层级较高,用户自定义的类加载器无法绕过它们来加载同名的系统类,从而防止了恶意代码伪装成系统类来执行,保证了系统的安全性。
  • 提高类加载的稳定性:双亲委派模型通过明确的类加载器层级关系,使得类的加载过程更加有序。不同的类加载器负责加载不同范围的类,这种分工明确的方式有助于提高整个类加载过程的稳定性,减少因类加载混乱而导致的程序错误。
  • 便于类的管理和维护:由于类加载是按照一定的层级关系进行的,所以对于类的管理和维护更加方便。可以通过控制类加载器的层级和加载范围,来实现对类的访问控制和管理。

劣势

  • 灵活性受限:双亲委派模型的类加载顺序是固定的,这种固定的加载顺序在某些情况下可能会限制应用的灵活性。例如,在一些特殊的应用场景中,可能需要打破双亲委派模型的常规加载顺序,按照自定义的方式来加载类,但双亲委派模型使得这种自定义加载变得困难。
  • 无法解决所有类加载问题:虽然双亲委派模型能够解决大多数类加载的安全性和一致性问题,但对于一些复杂的类加载场景,它可能无法完全满足需求。例如,在一些分布式系统或动态加载的应用中,可能需要更灵活的类加载机制来处理不同节点之间的类加载和版本兼容性问题。
  • 类加载过程复杂:双亲委派模型的类加载过程涉及多个类加载器之间的交互和委派,使得类加载过程相对复杂。这可能会增加应用开发和调试的难度,特别是在出现类加载错误时,定位和解决问题可能会比较困难。


原文地址:https://blog.csdn.net/gghfzs1/article/details/145123018

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!