類載入器(JVM)

小猴子_X發表於2022-02-07
一.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記憶體模型

本文只對類載入子系統進行展開,其他部分請看:https://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):​
      • 將常量池內的符號引用轉換為直接引用的過程。也有可能在初始化之後執行
  • 初始化(initialization):
    • 就是執行類的構造器方法<clinit>()的過程
    • 該方法無需定義,是javac編譯器自動收集類中的所有類變數的賦值動作靜態程式碼塊的語句合併而來的
    • 構造器方法中指令按語句在原始檔中出現的順序執行
    • 若該類有父類,先執行父類的<clinit>()再執行子類的
    • 虛擬機器必須保證一個類的<clinit>()方法在多執行緒下被同步加鎖
  • 使用
  • 解除安裝
三.類載入器分類
  • 引導類載入器(Bootstrap ClassLoader):
    • 使用c/c++編寫,用於載入java核心類庫(如java_home/jre/lib/rt.jar)
    • 只載入包名為:javajavaxsun開頭的
  • 自定義載入器:使用java編寫,所有繼承抽象類ClassLoader的載入器類都叫自定義載入類
    • 擴充套件類載入器(Extension ClassLoader)
      • 載入jre/lib/ext下的類庫,如果手動將自己的類放在該路徑下,也會被載入  
    • 系統(應用)類載入器(App ClassLoader)
      • 載入自己寫的類。是預設的載入器 
    • 使用者自定義載入器(User Defined ClassLoader)
      • 在日常的開發中,上述的三種載入器可以滿足絕大部分要求。但是,比如一些 框架,都會有自己的載入器。

注意:

三個類載入器:boostrap ClassLoader ,extension ClassLoader,App ClassLoader
不是繼承關係,而是上下級關係
 
獲取類的載入器的方法

四.類載入機制

雙親委派機制:
類進入載入器,先給老大載入。老大載入不了,才給小弟載入。也是為防止程式設計師惡意篡改核心檔案
為什麼要設計這種機制(好處)
  • 避免類的重複載入
  • 保護程式的安全,防止核心API被隨意篡改
    • 比如:如果有人想替換系統級別的類:String.java。篡改它的實現,在這種機制下這些系統的類已經被Bootstrap classLoader載入過了(為什麼?因為當一個類需要載入的時候,最先去嘗試載入的就是BootstrapClassLoader),所以其他類載入器並沒有機會再去載入,從一定程度上防止了危險程式碼的植入。

沙箱安全機制:
可以理解為雙親委派機制的一個體現,限制程式執行的環境,嚴格本地系統資源訪問。Java安全模型的核心就是Java沙箱(sandbox) 。
什麼是沙箱?
  • 沙箱是一個限制程式執行的環境。沙箱機制就是將Java程式碼限定在虛擬機器(JVM)特定的執行範圍中,並且嚴格限制程式碼對本地系統資源訪問,通過這樣的措施來保證對程式碼的有效隔離,防止對本地系統造成破壞。
  • 新的版本加入了域的概念,每個域有自己的許可權。

  •  舉例:自定義String也體現了沙箱安全機制。

 

 寄語:少研究別人,多塑造自己

相關文章