C++編程經驗(10):無鎖編程其實沒那么玄乎
670
2022-05-28
類加載機制
類加載過程分為 加載 >> 驗證 >> 準備 >> 解析 >> 初始化 >> 使用 >> 卸載 1、加載 在硬盤上查找并通過IO讀入字節碼文件,使用到類時才會加載,例如調用類的main()方法,new對象 等等,在加載階段會在內存中生成一個代表這個類的java.lang.Class對象,作為方法區這個類的各種數據的訪問入口 2、驗證 校驗字節碼文件的正確性 3、準備 給類的靜態變量分配內存,并賦予默認值 4、解析 將符號引用替換為直接引用,該階段會把一些靜態方法(符號引用,比如main()方法)替換為指向數據 所存內存的指針或句柄等(直接引用),這是所謂的靜態鏈接過程(類加載期間完成),動態鏈接是在程 序運行期間完成的將符號引用替換為直接引用,下節課會講到動態鏈接 5、初始化 對類的靜態變量初始化為指定的值,執行靜態代碼塊
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2、雙親委派機制(先找父親加載,不行再由兒子自己加載)
1、根類加載器(**Bootstrap classLoader**):負責加載支撐JVM運行的位于JRE的lib目錄下的核心類庫,比如rt.jar、charsets.jar等 2、擴展類加載器(**ExtClassLoader**):負責加載支撐JVM運行的位于JRE的lib目錄下的ext擴展目錄中的JAR類包 3、應用加載器(**AppClassLoader**):負責加載ClassPath路徑下的類包,主要就是加載你自己寫的那些類,負責加載用戶自定義路徑下的類包
1
2
3
4
5
類運行加載全過程會創建JVM啟動器實例sun.misc.Launcher。sun.misc.Launcher初始化使用了單例模式設計,保證一個JVM虛擬機內只有一個sun.misc.Launcher實例。在Launcher構造方法內部,其創建了兩個類加載器,分別是sun.misc.Launcher.ExtClassLoader(擴展類加載器)和sun.misc.Launcher.AppClassLoader(應用類加載器)。 JVM默認使用launcher的`getClassLoader()`方法返回的類加載器`AppClassLoader`的實例來加載我們的應用程序。
1
2
3
應用程序類加載器AppClassLoader加載類的雙親委派機制源碼,AppClassLoader的loadClass方法最終會調用其父類ClassLoader的loadClass方法,該方法的大體邏輯如下:
首先,檢查一下指定名稱的類是否已經加載過,如果加載過了,就不需要再加載,直接返回。
如果此類沒有加載過,那么,再判斷一下是否有父加載器;如果有父加載器,則由父加載器加載(即調用parent.loadClass(name, false);).或者是調用bootstrap類加載器來加載。
如果父加載器及bootstrap類加載器都沒有找到指定的類,那么調用當前類加載器的findClass方法來完成類加載。
1、沙箱安全機制:自己寫的java.lang.String.class類不會被加載,這樣便可以防止核心API庫被隨意篡改
2、避免類的重復加載:當父親已經加載了該類時,就沒有必要子ClassLoader再加載一次,保證被加載類的唯一性
“全盤負責”是指當一個ClassLoder裝載一個類時,除非顯示的使用另外一個ClassLoder,該類所依賴及引用的類也由這個ClassLoder載入
自定義類加載器只需要繼承 java.lang.ClassLoader 類,該類有兩個核心方法,一個是loadClass(String, boolean),實現了雙親委派機制,還有一個方法是findClass,默認實現是空方法,所以我們自定義類加載器主要是重寫findClass方法。
3、tomcat怎么破解類加載機制
1、commonLoader:Tomcat最基本的類加載器,加載路徑中的class可以被Tomcat容器本身以及各個Webapp訪問;
2、catalinaLoader:Tomcat容器私有的類加載器,加載路徑中的class對于Webapp不可見;
3、sharedLoader:各個Webapp共享的類加載器,加載路徑中的class對于所有Webapp可見,但是對于Tomcat容器不可見;
4、WebappClassLoader:各個Webapp私有的類加載器,加載路徑中的class只對當前Webapp可見,比如加載war包里相關的類, 每個war包應用都有自己的WebappClassLoader,實現相互隔離,比如不同war包應用引入了不同的spring版本,這樣實現就能加載各自的spring版本;
5、模擬實現Tomcat的JasperLoader熱加載
原理:后臺啟動線程監聽jsp文件變化,如果變化了找到該jsp對應的servlet類的加載器引用 (gcroot),重新生成新的JasperLoader加載器賦值給引用,然后加載新的jsp對應的servlet類,之前的那個加載器因為沒有gcroot引用了,下一次gc的時候會被銷毀
=>總結:每個webappClassLoader加載自己的目錄下的class文件,不會傳遞給父類加載器,打破了雙親委派機制。
JVM
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。