類加載機制
運行時數據區
類生命週期
類加載器
類加載器負責裝入類,搜索網絡、jar、zip、文件夾、二進制數據、內存等指定位置的類資源。
一個java程序運行,最少有三個類加載器實例,負責不同類的加載。
驗證問題:
- 查看類對應的加載器
- JVM如何知道我們的類在何方
- 類不會重複加載
- 類的卸載
- 雙親委派模型
查看類對應的加載器
/**
* 查看類的加載器實例
*/
public class ClassLoaderView {
public static void main(String[] args) throws Exception {
// 加載核心類庫的 BootStrap ClassLoader
System.out.println("核心類庫加載器:"
+ ClassLoaderView.class.getClassLoader().loadClass("java.lang.String").getClassLoader());
// 加載拓展庫的 Extension ClassLoader
System.out.println("拓展類庫加載器:" + ClassLoaderView.class.getClassLoader()
.loadClass("com.sun.nio.zipfs.ZipCoder").getClassLoader());
// 加載應用程序的
System.out.println("應用程序庫加載器:" + ClassLoaderView.class.getClassLoader());
// 雙親委派模型 Parents Delegation Model
System.out.println("應用程序庫加載器的父類:" + ClassLoaderView.class.getClassLoader().getParent());
System.out.println(
"應用程序庫加載器的父類的父類:" + ClassLoaderView.class.getClassLoader().getParent().getParent());
}
}
JVM如何知道我們的類在何方
class信息存放在不同的位置,桌面jar、項目bin目錄、target目錄等待…
查看openjdk源代碼:sun.misc.Launcher.AppClassLoader
結論:讀取java.class.path配置,指定去哪些地址加載類資源
驗證過程:利用jps、jcmd兩個命令
- jps查看本機JAVA進程
執行:jsp
- 查看運行時配置:jcmd進程號 VM.system_properties
執行:jcmd -help
執行:jcmd 6216 -help
執行:jcmd 6216 VM.system_properties
類不會重複加載
類的唯一性:同一個類加載器,類名一樣,代表是同一個類。
**識別方式:**ClassLoader Instance id + PackageName + ClassName
**驗證方式:**使用類加載器,對同一個class類的不同版本,進行多次加載,檢查是否會加載到最新的代碼。
類的卸載
類什麼時候會被卸載?
滿足以下兩個條件:
- 該Class所有的實例都已經被GC;
- 加載該類的ClassLoader實例已經被GC;
驗證方式:jvm啓動中增加 -verbose:class參數,輸出類加載和卸載的日誌信息
靜態代碼塊是在newInstance第一次創建對象的時候去加載的,不是在loadClass時候加載的,再次創建也不會進行加載
雙親委派模型
敗家子模型
邏輯上的上下關係
避免重複加載…安全性…
熱部署模式,每次用不同的類加載器去加載class