JVM双亲委派机制,沙箱安全机制

双亲委派机制的原理
如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器(Bootstrap ClassLoader)中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。

具体流程:

  1. 当AppClassLoader加载一个class时,它不会尝试加载这个类,而是把类加载请求委派给父类加载器ExtClassLoader去完成。

  2. 当父类ExtClassLoader加载到这个.class时,他也不会尝试加载这个类,而是把类加载请求委派给父类加载器BootstrapClassLoader。

  3. 当BootstrapClassLoader加载到这个.class时,它会查找该类是否存在,如果不存在,就往下传递,交给ExtClassLoader,如果ExtClassLoader在自己相应的包中也没找到对应的类,就交给AppClassLoader来加载,如果AppClassLoader也没有,就报ClassNotFoundException();
    在这里插入图片描述

双亲委派机制的优势

  1. 避免类的重复加载
  2. 保护程序安全,防止核心的API被篡改
    如何理解保护程序的安全,防止核心的API被篡改

加入我们自己创建了一个包名字叫做java.lang,里面自己写了个类叫做String, 里面修改String的固有方法。
我们再其他类中引用该类的时候,它并不会将java.lang.String类交给系统的类加载器加载,而是向上提交,启动类加载器发现是java.lang下的类于是启动类加载器处理,
但是发现里面的方法,发现调用原有的String中没有main方法,就抛出异常,这就避免了破环核心的API。

沙箱安全机制 防止代码的污染

比如我定义了一个类名为String所在包为java.lang,因为这个类本来是属于jdk的,如果没有沙箱安全机制的话,这个类将会污染到我所有的String,但是由于沙箱安全机制,所以就委托顶层的bootstrap加载器查找这个类,如果没有的话就委托extsion,extsion没有就到aapclassloader,但是由于String就是jdk的源代码,所以在bootstrap那里就加载到了,先找到先使用,所以就使用bootstrap里面的String,后面的一概不能使用,这就保证了不被恶意代码污染


在JVM中表示两个class对象是否为同一个类存在的两个必要条件

类的完整类名必须一致,包括包名
加载这个类的ClassLoader必须相同。

换句话说就是,在JVM中即使这两个类对象来源同一个Class文件,被同一个虚拟机栈加载,但是只要加载他们的ClassLoader实例对象不同,那么这两个类对象也是不相同的。

对类加载器的引用
JVM必须知道一个类型是由启动类加载器加载的还是由用户类加载器加载的。如果一个类型是由用户类加载器加载的,那么JVM 会将这个类加载器的一个引用作为类型信息的一部分保存在方法区中。当解析到一个类型到另一个类型的引用的时候,JVM需要保证这两个类型的类加载器是一样的。

猜你喜欢

转载自blog.csdn.net/qq_43079376/article/details/105779271