日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【JVM】详解类加载机制

發(fā)布時間:2023/12/29 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【JVM】详解类加载机制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

JVM的類加載機制

    • 一、類的生命周期
    • 二、類加載的過程
      • 1.加載
      • 2.連接
      • 3.初始化
    • 三、類加載器的介紹
      • 3.1 啟動類加載器(根類加載器/引導類加載器)(Bootstrap ClassLoader)
      • 3.2 擴展類加載器
      • 3.3 系統(tǒng)類加載器
    • 四、雙親委派模型
      • 4.1 雙親委派模型的優(yōu)點
      • 4.2 雙親委派模型的破壞

一、類的生命周期

對于一個類來說,它的生命周期是這樣的:

當程序主動使用某個類時,如果該類還未被加載到內存中,則JVM會通過加載、連接、初始化三個步驟對該類進行初始化。所以將這三個步驟稱為類加載
其中連接又分為三步:驗證、準備、解析

下面我們來仔細了解一下類加載的過程:

二、類加載的過程

1.加載

  • 加載是將類的class文件讀入到內存,并將這些靜態(tài)數(shù)據(jù)轉換成方法區(qū)中的運行時數(shù)據(jù)結構,并在堆中生成一個代表這個類的java.lang.Class對象,作為方法區(qū)類數(shù)據(jù)的訪問入口,這個過程需要類加載器參與。
  • 2.連接

    當類被加載之后,系統(tǒng)會為之生成一個對應的Class對象,接著將會進入連接階段,連接階段負責把類的二進制數(shù)據(jù)合并到JRE中(意思就是將java類的二進制代碼合并到JVM的運行狀態(tài)中)。

    類連接又可分為以下三個階段:

  • 驗證:確保加載的類信息是否符合JVM規(guī)范,有沒有安全方面的問題。主要驗證是否符合Class文件格式規(guī)范,并且是否能被當前的虛擬機加載處理。
  • 準備:正式為類中定義的變量(靜態(tài)變量)分配內存并設置類變量默認初始值階段,這些內存都將再方法區(qū)中進行分配。
  • 解析:虛擬機常量池的符號引用替換成直接引用的過程,也就是初始化變量的過程。 符號引用:是一組符號來描述所引用的目標,符號可以是任何的字面形式的字面量,只要不會出現(xiàn)沖突能夠定位到就行。布局和內存無關。 直接引用:是指向目標的指針,偏移量或者能夠直接定位的句柄,該引用是和內存中的布局有關的,并且一定加載進來的。
  • 3.初始化

    初始化是為類的靜態(tài)變量賦予正確的初始值,準備階段和初始化階段看似有點矛盾,其實不然。 比如這樣的一句代碼:private static int a=10;,在準備階段給a賦值是int類型的默認初始值0,到初始化這一階段才會把a真正的值10賦給它。

    三、類加載器的介紹

    類加載器就是在類加載階段實現(xiàn)“通過一個類的全限定名(包名+類名)來獲取類的二進制字節(jié)流”這個動作的。

    3.1 啟動類加載器(根類加載器/引導類加載器)(Bootstrap ClassLoader)

    它用來加載Java的核心類,是用原生代碼來實現(xiàn)的,并不繼承自java.lang.ClassLoader.由于啟動類加載器涉及到虛擬機本地實現(xiàn)細節(jié),開發(fā)者無法直接獲取到啟動類加載器的引用,所以不允許直接通過引用進行操作。負責加載擴展類加載器和系統(tǒng)類加載器,并為他們的指定父類加載器。

    3.2 擴展類加載器

    由Java語言編寫的,派生于ClassLoader類,上層類加載器為啟動類加載器。它負責加載JRE/lib/ext目錄下的類。

    3.3 系統(tǒng)類加載器

    Java語言編寫,派生于ClassLoader類,上層類加載器為擴展類加載器。負責加載我們自己定義的類。

    四、雙親委派模型

    工作原理:如果一個類加載器收到了類加載請求,它并不會自己先去加載,而是把這個請求委托給父類加載器去執(zhí)行,如果費雷加載器還存在其父類加載器,則進一步向上委托,一次遞歸,請求最終將到達頂層的啟動類加載器。如果父類加載器可以完成類加載任務,就成功返回,如果父類加載器無法完成此加載任務,子加載器才會嘗試自己去加載,這就是雙親委派模式。
    也就是每個兒子都很懶,每次有活交給父親去干,直到父親說這件事我也干不了的時候,兒子才自己想辦法。

    4.1 雙親委派模型的優(yōu)點

    • 避免類的重復加載:比如A類和B類都有一個父類C類,那么A啟動時就會將C類加載起來,那么B類進行加載的時候就不需要重復加載C類了。
    • 安全性:使用雙親委派模型可以保證Java核心API不被篡改。假設通過網(wǎng)絡傳遞一個名為java.lang.Integer的類,通過雙親委派莫辛納甘傳遞到啟動類加載器,而啟動類加載器在核心Java API發(fā)現(xiàn)這個名字的類,發(fā)現(xiàn)該類已經(jīng)被加載了,并不會重新加載網(wǎng)絡傳遞過來的java.lang.Integer類,而是直接返回已加載過的Integer.class,這樣便可以防止核心API庫被隨便篡改。

    4.2 雙親委派模型的破壞

    雙親委派模型的弊端:不能向下委派,不能不委派。
    那么我們要打破雙親委派模型:也就是能向下委派和不委派。

    向下委派:SPI機制

    SPI機制
    SPI機制是一種服務發(fā)現(xiàn)機制。它通過在ClassPath路徑下的META-INF/services文件夾查找文件,自動加載文件里定義的類。這一機制為很多框架擴展提供了可能,比如在JDBC中就使用到了SPI機制。

    SPI機制如何打破雙親委派模型:
    在某些情況下父類加載器需要委托子類加載器去加載class文件。受加載范圍的限制,父類加載器無法加載到需要的文件。
    以Drive接口為例,DriverManger通過啟動類加載器加載進來,而com.mysql.jdbc.Driver是通過系統(tǒng)類加載器加載進來的。由于雙親委派模型父類加載器是拿不到通過子加載器加載的類的。這個時候就需要啟動類加載器來委托子類加載器來加載Driver實現(xiàn),從而破壞了雙親委派模型。

    總結

    以上是生活随笔為你收集整理的【JVM】详解类加载机制的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。