類加載器(JVM)
一.JVM概述
JVM是java是二進制位元組碼的運行環境
特點:
- 一次編譯,到處運行(跨平台)
- 自動內存管理
- 自動垃圾回收功能
常見的JVM
- Sun Classic VM:世界上第一款商用的java虛擬機,但是這款虛擬機只提供解釋器,不提供編譯器。
- HotSpot VM :由sun公司開發,是jdk默認的虛擬機,佔據絕對的市場地位
- 主要是它的熱點代碼探測技術 ,通過編譯器和解釋器協同工作,在最優化的程序響應時間與最佳執行性能中取得平衡
- JRockit :由BEA公司開發,已被oracle收購 ,專註於服務端應用。
- 不包含解釋器實現,全部代碼由編譯器執行,是世界上最快的JVM。適用於軍事,財務等
- jdk8.0其實就是oracle在hotspot的基礎上整合了JRockit的優秀特徵
- J9:IBM開發,廣泛應用於IBM的各種java產品。
- 在自己的產品中使用的話,號稱世界最快JVM
JVM內存模型
本文只對類加載子系統進行展開,其他部分請看://www.cnblogs.com/monkey-xuan/p/15656666.html
二.類加載子系統概述
類加載子系統就是把位元組碼文件加載到JVM內存中。類加載器只負責class文件的加載,至於是否可以運行,就由執行引擎決定了 加載的類的信息存放在方法區中
類加載的過程:
- 加載(loading):
- 通過一個類的權限定名(絕對路徑),獲取此類的二進制位元組流
- 在內存中生成Class對象,作為這個類的訪問入口
- 鏈接(linking):
- 驗證(verify):
- 確保class文件的信息符合jvm的規範要求。
- 包括:文件格式驗證,元數據驗證,位元組碼驗證,符號應用驗證
- 準備(prepare):
- 為類變量(static修飾)分配內存,並設置默認初始值。比如int為0,double為0.00
- 但是final修飾static時就是常量,常量在編譯期間就進行顯式賦值並分配了 (因為常量必須要求是顯示賦值,所以壓根不存在初始化)
- 解析(resolve):
- 將常量池內的符號引用轉換為直接引用的過程。也有可能在初始化之後執行
- 驗證(verify):
- 初始化(initialization):
- 就是執行類的構造器方法<clinit>()的過程
- 該方法無需定義,是javac編譯器自動收集類中的所有類變量的賦值動作和靜態代碼塊的語句合併而來的
- 構造器方法中指令按語句在源文件中出現的順序執行
- 若該類有父類,先執行父類的<clinit>()再執行子類的
- 虛擬機必須保證一個類的<clinit>()方法在多線程下被同步加鎖
- 使用
- 卸載
三.類加載器分類
- 引導類加載器(Bootstrap ClassLoader):
- 使用c/c++編寫,用於加載java核心類庫(如java_home/jre/lib/rt.jar)
- 只加載包名為:java,javax,sun開頭的
- 自定義加載器:使用java編寫,所有繼承抽象類ClassLoader的加載器類都叫自定義加載類
- 擴展類加載器(Extension ClassLoader)
- 加載jre/lib/ext下的類庫,如果手動將自己的類放在該路徑下,也會被加載
- 系統(應用)類加載器(App ClassLoader)
- 加載自己寫的類。是默認的加載器
- 用戶自定義加載器(User Defined ClassLoader)
- 在日常的開發中,上述的三種加載器可以滿足絕大部分要求。但是,比如一些 框架,都會有自己的加載器。
- 擴展類加載器(Extension ClassLoader)
注意:
三個類加載器:boostrap ClassLoader ,extension ClassLoader,App ClassLoader
不是繼承關係,而是上下級關係
獲取類的加載器的方法

四.類加載機制
雙親委派機制:
類進入加載器,先給老大加載。老大加載不了,才給小弟加載。也是為防止程序員惡意篡改核心文件
為什麼要設計這種機制(好處)
-
避免類的重複加載
-
保護程序的安全,防止核心API被隨意篡改
-
比如:如果有人想替換系統級別的類:String.java。篡改它的實現,在這種機制下這些系統的類已經被Bootstrap classLoader加載過了(為什麼?因為當一個類需要加載的時候,最先去嘗試加載的就是BootstrapClassLoader),所以其他類加載器並沒有機會再去加載,從一定程度上防止了危險代碼的植入。
-
沙箱安全機制:
可以理解為雙親委派機制的一個體現,限制程序運行的環境,嚴格本地系統資源訪問。Java安全模型的核心就是Java沙箱(sandbox) 。
什麼是沙箱?
- 沙箱是一個限制程序運行的環境。沙箱機制就是將Java代碼限定在虛擬機(JVM)特定的運行範圍中,並且嚴格限制代碼對本地系統資源訪問,通過這樣的措施來保證對代碼的有效隔離,防止對本地系統造成破壞。
- 新的版本加入了域的概念,每個域有自己的權限。
- 舉例:自定義String也體現了沙箱安全機制。
寄語:少研究別人,多塑造自己