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 ]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章