【JVM】详解类加载机制
JVM的類加載機制
- 一、類的生命周期
- 二、類加載的過程
- 1.加載
- 2.連接
- 3.初始化
- 三、類加載器的介紹
- 3.1 啟動類加載器(根類加載器/引導類加載器)(Bootstrap ClassLoader)
- 3.2 擴展類加載器
- 3.3 系統類加載器
- 四、雙親委派模型
- 4.1 雙親委派模型的優點
- 4.2 雙親委派模型的破壞
一、類的生命周期
對于一個類來說,它的生命周期是這樣的:
當程序主動使用某個類時,如果該類還未被加載到內存中,則JVM會通過加載、連接、初始化三個步驟對該類進行初始化。所以將這三個步驟稱為類加載。
其中連接又分為三步:驗證、準備、解析。
下面我們來仔細了解一下類加載的過程:
二、類加載的過程
1.加載
2.連接
當類被加載之后,系統會為之生成一個對應的Class對象,接著將會進入連接階段,連接階段負責把類的二進制數據合并到JRE中(意思就是將java類的二進制代碼合并到JVM的運行狀態中)。
類連接又可分為以下三個階段:
3.初始化
初始化是為類的靜態變量賦予正確的初始值,準備階段和初始化階段看似有點矛盾,其實不然。 比如這樣的一句代碼:private static int a=10;,在準備階段給a賦值是int類型的默認初始值0,到初始化這一階段才會把a真正的值10賦給它。
三、類加載器的介紹
類加載器就是在類加載階段實現“通過一個類的全限定名(包名+類名)來獲取類的二進制字節流”這個動作的。
3.1 啟動類加載器(根類加載器/引導類加載器)(Bootstrap ClassLoader)
它用來加載Java的核心類,是用原生代碼來實現的,并不繼承自java.lang.ClassLoader.由于啟動類加載器涉及到虛擬機本地實現細節,開發者無法直接獲取到啟動類加載器的引用,所以不允許直接通過引用進行操作。負責加載擴展類加載器和系統類加載器,并為他們的指定父類加載器。
3.2 擴展類加載器
由Java語言編寫的,派生于ClassLoader類,上層類加載器為啟動類加載器。它負責加載JRE/lib/ext目錄下的類。
3.3 系統類加載器
Java語言編寫,派生于ClassLoader類,上層類加載器為擴展類加載器。負責加載我們自己定義的類。
四、雙親委派模型
工作原理:如果一個類加載器收到了類加載請求,它并不會自己先去加載,而是把這個請求委托給父類加載器去執行,如果費雷加載器還存在其父類加載器,則進一步向上委托,一次遞歸,請求最終將到達頂層的啟動類加載器。如果父類加載器可以完成類加載任務,就成功返回,如果父類加載器無法完成此加載任務,子加載器才會嘗試自己去加載,這就是雙親委派模式。
也就是每個兒子都很懶,每次有活交給父親去干,直到父親說這件事我也干不了的時候,兒子才自己想辦法。
4.1 雙親委派模型的優點
- 避免類的重復加載:比如A類和B類都有一個父類C類,那么A啟動時就會將C類加載起來,那么B類進行加載的時候就不需要重復加載C類了。
- 安全性:使用雙親委派模型可以保證Java核心API不被篡改。假設通過網絡傳遞一個名為java.lang.Integer的類,通過雙親委派莫辛納甘傳遞到啟動類加載器,而啟動類加載器在核心Java API發現這個名字的類,發現該類已經被加載了,并不會重新加載網絡傳遞過來的java.lang.Integer類,而是直接返回已加載過的Integer.class,這樣便可以防止核心API庫被隨便篡改。
4.2 雙親委派模型的破壞
雙親委派模型的弊端:不能向下委派,不能不委派。
那么我們要打破雙親委派模型:也就是能向下委派和不委派。
向下委派:SPI機制
SPI機制
SPI機制是一種服務發現機制。它通過在ClassPath路徑下的META-INF/services文件夾查找文件,自動加載文件里定義的類。這一機制為很多框架擴展提供了可能,比如在JDBC中就使用到了SPI機制。
SPI機制如何打破雙親委派模型:
在某些情況下父類加載器需要委托子類加載器去加載class文件。受加載范圍的限制,父類加載器無法加載到需要的文件。
以Drive接口為例,DriverManger通過啟動類加載器加載進來,而com.mysql.jdbc.Driver是通過系統類加載器加載進來的。由于雙親委派模型父類加載器是拿不到通過子加載器加載的類的。這個時候就需要啟動類加載器來委托子類加載器來加載Driver實現,從而破壞了雙親委派模型。
總結
以上是生活随笔為你收集整理的【JVM】详解类加载机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 美国芝加哥sk服务器哪个系统好,美国服务
- 下一篇: 【EOS钱包开发 一】EOS不得不说的一