虛擬機系列 | JVM類加載機制

2020-10-03 Java架構師技術棧分享

一、類加載簡介

類的加載機制是指把編譯後的.class類文件的二進位數據讀取到內存中,並為之創建一個java.lang.Class對象,用來封裝類在元數據空間的數據結構。

類在JVM中的生命周期為:加載,連接,初始化,使用,卸載。不過這裡只重點描述加載,連接,初始化這三個過程。

二、加載過程

基於一張圖看懂加載子系統的細節流程:

1、加載階段

過程描述

加載階段需要完成以下三個過程:

  • 通過類的全限定名來獲取其定義的二進位字節流;
  • 將字節流所代表的靜態存儲結構轉化為雲數據空間的運行時數據結構;
  • 在堆Heap中生成一個代表這個類的java.lang.Class對象,作為對元數據空間中這些數據的訪問入口;

類加載器

  • 引導類加載器

Bootstrap-ClassLoader基於C/C++實現,負責加載Java的核心類庫JAVA_HOME\jre\lib\rt.jar,該加載器不繼承自ClassLoader抽象類,並且只加載包名為java、javax、sun等開頭類,一次保證對核心源碼的保護。

  • 擴展類加載器

Extension-ClassLoader,基於Java語言,由sun.misc.Launcher$ExtClassLoader實現,派生於ClassLoader抽象類,從java.ext.dirs系統變量指定的路徑中的加載類庫,或者JDK安裝目錄jre\lib\ext目錄下加載。

  • 系統類加載器

Application-ClassLoader,基於Java語言,由sun.misc.Launcher$ExtClassLoader實現,它負責加載環境變量ClassPath指定的類庫,如果在應用程式中沒有自定義類加載器,一般情況下作為程序中默認的類加載器。

2、連接階段

驗證

目的在於確保Class文件的字節流中包含的信息符合當前虛擬機的要求,保證加載類的正確性,不會危害虛擬機自身的安全,主要包括四種檢驗動作:

  • 文件格式驗證:驗證字節流是否符合Class文件格式的規範;
  • 元數據驗證:確保其描述的信息符合Java語言規範的要求;
  • 字節碼驗證:確定程序語義是符合邏輯的;
  • 符號引用驗證:確保解析動作能正確執行。

準備

為類的靜態變量分配內存,並初始化為默認值,這時候進行內存分配的僅包括類變量(static)修飾,不包括(final-static)修飾的,這裡也不會為實例變量分配初始化,實例變量會隨著對象一塊分配到Java堆中。

解析

將常量池中的符號引用轉換為直接引用的過程,直接引用就是直接指向目標的指針、相對偏移量或一個間接定位到目標的句柄。解析主要針對類或接口、欄位、類方法、接口方法、方法類型等,解析的動作實際是會隨著JVM在執行完初始化之後再執行的。

3、初始化階段

執行類構造器clinit()方法的過程,該方法不需要自定義,是javac編譯器自動收集類中的所有類變量的賦值動作和靜態代碼塊中的語句合併而來,Jvm要保證clinit()方法在多線程訪問下的安全性。

三、機制策略

1、雙親委派模式

類加載器收到了類加載的請求時,不會自己先去嘗試加載這個類,而是把請求委託給父加載器去執行;

如果父加載器還存在父類加載器,則依次向上委託,因此類加載請求最終都應該被傳遞到頂層的啟動類加載器中;

如果父類加載器可以完成類加載請求,就直接成功返回,只有當父加載器在無法完成該加載,子加載器才會嘗試自己去加載該類;

2、沙箱安全機制

假設自定義一個類名為String且所在包為java.lang,在使用引導類加載器加載時會先加載JDK中的String類,因為這個類本來是屬於jdk的,後面再次出現String類就會報錯,以此保證原始碼不被惡意篡改,這就是沙箱安全機制。

相關焦點

  • 大白話談JVM的class類加載機制
    JVM什麼時候加載類其實說到類加載的底層機制,這是一個很複雜的過程,但是對於我們平時的工作來講,只要懂得它的核心原理就可以了。一個類的加載過程會經歷如下的幾個過程:加載、驗證、準備、解析、初始化、使用、卸載首先我們就先弄明白一個問題,jvm是什麼時候去加載類的呢?
  • 深入淺出JVM性能調優——JVM內存模型和類加載運行機制
    JVM 不僅承擔了 Java 字節碼的分析和執行,同時也內置了自動內存分配管理機制。這個機制可以大大降低手動分配回收機制可能帶來的內存洩露和內存溢出風險,使 Java 開發人員不需要關注每個對象的內存分配以及回收,從而更專注於業務本身。
  • 關於JVM類加載機制,看這一篇就夠了
    類的加載機制Java虛擬機把描述類的數據從Class文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這個過程被稱作虛擬機的類加載機制。.class文件加載到jvm中之外,還會對類進行解釋,執行類中的static塊;ClassLoader.loadClass(): 只幹一件事情,就是將.class文件加載到jvm中,不會執行static中的內容,只有在newInstance才會去執行static塊。
  • 妙啊,一文解析虛擬機系列 | JVM類加載機制
    類的加載機制是指把編譯後的.class類文件的二進位數據讀取到內存中,並為之創建一個java.lang.Class對象,用來封裝類在元數據空間的數據結構。的要求,保證加載類的正確性,不會危害虛擬機自身的安全,主要包括四種檢驗動作:文件格式驗證:驗證字節流是否符合Class文件格式的規範;元數據驗證:確保其描述的信息符合Java語言規範的要求;字節碼驗證:確定程序語義是符合邏輯的;符號引用驗證:確保解析動作能正確執行。
  • JVM加載class文件的原理機制詳解
    NO ,NO , JVM 是一個內存中的虛擬機,那它的存儲就是內存了,我們寫的所有類、常量、變量、方法都在內存中,這決定著我們程序運行的是否健壯、是否高效,接下來的部分就是重點介紹之。  類裝載方式,有兩種   1.隱式裝載, 程序在運行過程中當碰到通過new 等方式生成對象時,隱式調用類裝載器加載對應的類到jvm中,   2.顯式裝載, 通過class.forname()等方法,顯式加載需要的類   隱式加載與顯式加載的區別:兩者本質是一樣?
  • 一文徹底搞懂|JVM 類加載機制
    學習導圖一.為什麼要學習類加載機制?今天想跟大家嘮嗑嘮嗑Java的類加載機制,這是Java的一個很重要的創新點,曾經也是Java流行的重要原因之一。Oracle當初引入這個機制是為了滿足Java Applet開發的需求,JVM咬咬牙引入了Java類加載機制,後來的基於Jvm的動態部署,插件化開發包括大家熱議的熱修復,總之很多後來的技術都源於在JVM中引入了類加載器。如今,類加載機制也在各個領域大放異彩,在面試中,由類加載機制所衍生出來各類面試題也層出不窮。
  • JVM性能調優——JVM內存模型和類加載運行機制
    JVM 不僅承擔了 Java 字節碼的分析和執行,同時也內置了自動內存分配管理機制。這個機制可以大大降低手動分配回收機制可能帶來的內存洩露和內存溢出風險,使 Java 開發人員不需要關注每個對象的內存分配以及回收,從而更專注於業務本身。
  • JVM入門(一)類的加載過程
    如果我們是以jar的方式進行運行java程序,那麼執行 :java -jar *.jar com.xx.Hello 起中 Hello是這個jar中包含了main方法的類的名稱。無論是那種方式,當我們執行的時候,就會啟動jvm虛擬機去加載所要執行的Hello.class文件到虛擬機中。
  • 深入解析JVM類加載器子系統,你還不了解的都在這裡
    虛擬機要求,保證被加載類的正確性,不會危害虛擬機自身安全。Clinit不同於類的構造器(構造器是虛擬機視角下的init())若該類有父類,jvm會保證子類的clinit()執行前,父類的clinit()已經執行完畢虛擬機必須保證一個類的clinit()在多線程下被同步加載。
  • java類加載機制和類加載器
    類加載機制java類從被加載到JVM到卸載出JVM,整個生命周期包括:加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(using)、和卸載(Unloading)七個階段。其中驗證、準備和解析三個部分統稱為連接(Linking)。
  • 詳解JVM類加載
    1.1 類加載檢查虛擬機遇到一條new指令時,首先檢查這個指令的參數是否能在常量池中定位到這個類的符號引用,並且檢查這個符號引用代表的類是否已被加載、解析和初始化過。如果沒有,就必須執行相應的類加載過程。1.2 分配內存在類加載檢查通過後,虛擬機將為新生對象分配內存。
  • Java類加載機制,你理解了嗎?
    我們知道,我們寫的java文件是不能直接運行的,我們可以在IDEA中右鍵文件名點擊運行,這中間其實摻雜了一系列的複雜處理過程。這篇文章,我們只討論我們的代碼在運行之前的一個環節,叫做類的加載。按照我寫文章的常規慣例,先給出這篇文章的大致結構;首先,認識類加載機制,然後,詳細介紹類加載的過程。最後,介紹了類加載器,還有雙親委派原則。
  • JVM的雙親委派機制
    JVM的雙親委派機制JVM類加載器是什麼機制?為什麼使用這種機制(這種機制的好處是什麼)?說下類加載流程?用代碼驗證類加載機制。為什麼要破壞類的這種加載機制?JVM雙親委派機制,簡單來說:我爸是李剛,有事找我爸。用三個字來說:往上捅。不信?咱們一起看看我們已經知道了JVM類加載器的四種加載機制,那麼這四種加載機制是怎麼個加載過程呢?
  • JVM中Java類的生命周期,一文搞定
    但是,如果將jvm只與Java語言綁定在一起,那麼理解就過於狹隘了,Java虛擬機發展到現在已經脫離了Java語言,形成了一套相對獨立,高性能的執行方案。這些類加載器需要先由另一個類加載器,比如說啟動類加載器,加載至 Java 虛擬機中,方能執行類加載。標準擴展(Extension)類加載器它負責加載相對次要、但又通用的類,負責將 JAVA_HOME/jre/lib/ext 或者由系統變量 java.ext.dirs指定位置中的類庫加載到內存中。
  • 20張圖解密JVM類加載子系統,瞬間豁然開朗
    要求,保證被加載類的正確性,不會危害虛擬機自身安全。而且加載某個類的class文件時,java虛擬機採用的是雙親委派模式,即把請求交由父類處理,它是一種任務委派模式。所以Java虛擬機先從最可信的Java核心API查找類型,這是為了防止不可靠的類扮演被信任的類,試想一 下,網絡上有個名叫java.lang.Integer的類,它是某個黑客為了想混進java.lang包所起的名字,實際上裡面含有惡意代碼,但是這種伎倆在雙親模式加載體系結構下是行不通的,因為網絡類加載器在加載它的時候,它首先調用雙親類加載器,這樣一直向上委託,直到啟動類加載器,而啟動類加載器在核心Java
  • Java高級之虛擬機加載機制
    ,都知道Jvm要加載的是二進位流,可以是.class文件形式,也可以是其他形式,總之按照它加載的標準來設計就不會有太大問題,以下主要就機制和標準兩個問題分析一番首先來說 Java類文件的加載機制 ,跟變量的加載機制類似,它先把Class文件加載入內存,再對數據進行驗證、解析和初始化,最終形成虛擬機可以直接使用的Java類型。
  • 你有真正理解 Java 的類加載機制嗎?|原力計劃
    作者 | 宜春責編 | Elle出品 | CSDN 博客你是否真的理解Java的類加載機制?點進文章的盆友不如先來做一道非常常見的面試題,如果你能做出來,可能你早已掌握並理解了Java的類加載機制,若結果出乎你的意料,那就很有必要來了解了解Java的類加載機制了。
  • JVM之類加載機制
    在java虛擬機中,類是在運行期間第一次使用時動態加載的,而不是一次性加載所有類。因為如果一次性加載,那麼會佔用很多的內存。類的生命周期分為7個階段:加載、驗證、準備、解析、初始化、使用、卸載。加載加載是類加載的一個階段,注意不要混淆。加載過程完成以下三件事:通過類的完全限定名稱獲取定義該類的二進位字節流。將該字節流表示的靜態存儲結構轉換為方法區的運行時存儲結構。
  • JAVA類的加載機制
    一、類的加載機制虛擬機把描述類的數據從Class文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制。三、類的加載過程接下來詳細講解一下Java虛擬機中類加載的全過程,也就是加載、驗證、準備、解析和初始化這五個階段所執行的具體動作。
  • jvm - 深入理解Java類加載
    ;理解各個類加載器特別是線程上下文加載器;Java虛擬機類加載機制虛擬機把描述類的數據從 Class文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的 Java 類型,這就是虛擬機的類加載機制。