JVM-双亲委派机制

双亲委派机制原理

package basic;
import java.util.HashMap;
public class ClassLoaderDemo {
      public static void main(String[] args) {
            // C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar
            HashMap<String, String> map = new HashMap<>(); 

            Demo1 demo1 = new Demo1();
            System.out.println(map.getClass().getClassLoader());
            System.out.println(demo1.getClass().getClassLoader());
      }
}

运行结果:

null // 启动类加载器由C++实现,Java无法打印出其引用。
sun.misc.Launcher$AppClassLoader@2a139a55
1. check ClassLoaderDemo 是否有父类加载器,存在,是扩展类加载器。
 
2. 不直接加载扩展类加载器,check扩展类加载器是否有父类,存在,是根类加载器。
 
3. check根类加载器是否有父类,没有。
 
    3.1 根类加载器去加载ClassLoaderDemo (%JAVA_HOME%Jjre\lib)
 
    3.2 找不到,告诉子类加载器扩展类加载器。
 
4. 扩展类加载器去%JAVA_HOME%\lib\ext寻找,找不到,告诉子类加载器“AppClassLoader”
 
5. AppClassLoader找到了,将ClassLoaderDemo 加载到内存中,生成class对象。
 

参考链接:https://www.cnblogs.com/wang-meng/p/5574071.html

双亲委派机制优点

  • 安全机制
比如自己写的String.class类不会被加载,这样可以防止核心库被随意篡改。
 
package basic;
public class String {
      static {
            System.out.println("my string started...");
      }
      
      public static void main(String[] args) {
            String string = new String();
            System.out.println(string);
      }
}

运行结果:

错误: 找不到或无法加载主类 basic.String

String向上委托至启动类加载器,但是启动类加载只会加载rt.jar中的String。自定义的String不会被加载,因此报错“找不到或无法加载主类 basic.String”。这样可以防止恶意注入,例如注入擦除磁盘的操作,如果自定义String生效会导致磁盘数据丢失,影响数据安全。

如何打破双亲委派机制

  • 使用自定义类加载

Tomcat为了实现隔离性和热替换,没有使用默认的类加载器,而是自己实现了类加载器: [ https://www.cnblogs.com/june0816/p/10090428.html ]

猜你喜欢

转载自blog.csdn.net/A_bad_horse/article/details/106079690