欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JVM分析之類加載機(jī)制詳解

 更新時(shí)間:2022年08月10日 08:35:33   作者:指北君  
JVM內(nèi)部架構(gòu)包含類加載器、內(nèi)存區(qū)域、執(zhí)行引擎等。日常開發(fā)中,我們編寫的java文件被編譯成class文件后,jvm會(huì)進(jìn)行加載并運(yùn)行使用類。本次將對(duì)JVM加載部分進(jìn)行分析,便于大家了解并掌握加載機(jī)制

1、前言

JVM內(nèi)部架構(gòu)包含類加載器、內(nèi)存區(qū)域、執(zhí)行引擎等。日常開發(fā)中,我們編寫的java文件被編譯成class文件后,jvm會(huì)進(jìn)行加載并運(yùn)行使用類。本次僅對(duì)JVM加載部分進(jìn)行分析,了解并掌握加載機(jī)制。

2、類加載是什么

類加載是一種過(guò)程,是將class文件加載到j(luò)vm內(nèi)存的過(guò)程。當(dāng)代碼邏輯中需要引用類時(shí),通過(guò)類加載器加載引用類對(duì)象并存放堆中,以供代碼調(diào)用。

3、類加載過(guò)程

注:類加載過(guò)程包含 加載、鏈接(驗(yàn)證、準(zhǔn)備、解析)、初始化

3.1 加載

加載:將類的class字節(jié)碼文件讀到內(nèi)存,將其存放到運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū),然后在堆區(qū)生成class對(duì)象,封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。(方法區(qū)-》數(shù)據(jù)結(jié)構(gòu),堆區(qū)-》class對(duì)象)

過(guò)程:java文件-》通過(guò)java c編譯成字節(jié)碼.class文件-》引導(dǎo)類加載器(裝載核心類庫(kù))-》擴(kuò)展類加載器(將指定目錄jar包裝載至工作庫(kù))-》系統(tǒng)類加載器(將指定目錄的類和jar包裝載至工作庫(kù),常用)-》自定義類加載器(實(shí)現(xiàn)加載指定類或自定義加密等操作)

緩存:類加載到j(luò)vm后,會(huì)緩存一段時(shí)間(不管是否被引用),待jvm執(zhí)行垃圾回收時(shí)才會(huì)回收未使用的緩存類,釋放空間。

類加載器:

  • 啟動(dòng)類加載器:Bootstrap ClassLoader由C/C++實(shí)現(xiàn),嵌套在JVM中,java程序無(wú)法直接操作;負(fù)責(zé)加載Java核心類庫(kù)($JAVA_HOME中jre/lib目錄下或-Xbootclasspath參數(shù)指定的路徑目錄下,如java.*開頭的類)的class文件。
  • 擴(kuò)展類加載器:Extension ClassLoader由Java編寫,由sun.misc.Launcher$ExtClassLoader實(shí)現(xiàn)。加載java平臺(tái)擴(kuò)展的jar包,負(fù)責(zé)加載(java.ext.dirs目錄或$JAVA_HOMEjre/lib/ext目錄,如javax.開頭的類)的class文件。
  • 應(yīng)用程序類加載器:Application ClassLoader由Java編寫,由sun.misc.Launcher$AppClassLoader實(shí)現(xiàn)。負(fù)責(zé)加載用戶類路徑(classpath)的class文件,java程序一般默認(rèn)使用應(yīng)用程序類加載器。
  • 自定義類加載器:一般情況下java程序使用上面三種類加載器就滿足了,一些特殊情況下,我們需要自定義加載指定路徑的類時(shí),就需要繼承java.lang.ClassLoader類,重寫find Class或loadClass均可實(shí)現(xiàn)。(類隔離實(shí)踐中就采用此方案)

類加載機(jī)制

  • 全盤負(fù)責(zé):當(dāng)加載器加載某個(gè)class時(shí),該class所引用的其他class也一并被加載(自定義加載class除外);
  • 緩存機(jī)制:所有加載過(guò)的class均被緩存,當(dāng)程序中使用某個(gè)class時(shí),優(yōu)先從緩存區(qū)中獲取,如果緩存區(qū)不存在,才會(huì)讀取該class的字節(jié)碼文件,加載為class對(duì)象,并存入緩存區(qū),以便后續(xù)使用。(修改class后,需要重啟jvm才會(huì)生效)
  • 雙親委派:是一種類加載安全機(jī)制,當(dāng)類加載器需要加載某個(gè)class文件時(shí),會(huì)優(yōu)先把加載委托給父類加載器處理,如果加載成功則返回,否則繼續(xù)向上委托直至最頂層類加載器,當(dāng)父類加載器在加載范圍內(nèi)均沒(méi)有找到所需class文件,即表示無(wú)法完成加載,此時(shí)子加載器才會(huì)去加載。(先向上委托父類加載器處理,都失敗后在自己再加載)
  • 反向委派:主要是用于第三方包加載,第三方包的類不在jdk/lib目錄,所以Bootstrap ClassLoader引導(dǎo)類加載器無(wú)法直接加載SPI(Service Provider Interface,服務(wù)提供者接口)的實(shí)現(xiàn)類,雙親委派機(jī)制中定義無(wú)法反向委托Application Classloader系統(tǒng)加載器加載,因此需要一種特殊的ContextClassLoader線程上下文類加載器來(lái)加載第三方的類庫(kù)。(*** 此處SPI接口后續(xù)文章分析 ***)

加載實(shí)現(xiàn)方式

?/*
??*?類加載方式
??*?1、類加載器,此方式加載的class對(duì)象還沒(méi)有完成鏈接階段
??*?2、java.lang.Class,此方式加載的class對(duì)象是完成初始化的
??*?*/
?ClassLoader?classLoader?=?ClassSegregationTest.class.getClassLoader();
?classLoader.loadClass("com.lgy.example.class_segregation.SegregationTestA");
?//?默認(rèn)初始化class對(duì)象
?Class.forName("com.lgy.example.class_segregation.SegregationTestA");
?//?默認(rèn)不初始化,并且指定類加載器進(jìn)行加載
?Class.forName("com.lgy.example.class_segregation.SegregationTestA",?false,?classLoader);

3.2 鏈接

鏈接是將java二進(jìn)制代碼合并至jvm運(yùn)行的過(guò)程。

鏈接過(guò)程可分為 驗(yàn)證、準(zhǔn)備、解析 三個(gè)階段。

驗(yàn)證

保證正確加載類,包括文件格式驗(yàn)證(Class文件格式的規(guī)范)、元數(shù)據(jù)驗(yàn)證(Java語(yǔ)言規(guī)范)、字節(jié)碼驗(yàn)證(通過(guò)數(shù)據(jù)流和控制流分析)、符號(hào)引用驗(yàn)證。

準(zhǔn)備

  • 在方法區(qū)為靜態(tài)變量(static修飾)分配內(nèi)存,并設(shè)置類變量初始值(通常是數(shù)據(jù)類型默認(rèn)的零值,如0,0L,null,false等)。
  • 顯示賦值是在類對(duì)象實(shí)例化時(shí)處理(即 public static int x=10,準(zhǔn)備階段初始值為0,在對(duì)象實(shí)例化時(shí),才被賦值10)

解析

  • 虛擬機(jī)中將常量池的符號(hào)引用(常量名)替換為直接引用(目標(biāo)的指針地址)的過(guò)程;
  • 符號(hào)引用的目標(biāo)不一定在內(nèi)存中,但常量名(或稱字面量)是明確定義在jvm規(guī)范的class文件格式中。
  • 直接引用是指向目標(biāo)的指針地址、相對(duì)偏移量或間接定位到目標(biāo)的句柄,是肯定在內(nèi)存中。

3.3 初始化

執(zhí)行每個(gè)類的構(gòu)造方法init()的過(guò)程,init()方法是java編譯器自動(dòng)收集、合并所有類變量的賦值動(dòng)作和靜態(tài)代碼塊語(yǔ)句,完成初始化。

初始化步驟

  • 類未被加載或鏈接,則程序先加載并鏈接該類
  • 優(yōu)先初始化直接父類,再執(zhí)行子類初始化
  • 依次執(zhí)行類中的初始化語(yǔ)句

初始化條件(只有對(duì)類主動(dòng)使用時(shí)才會(huì)初始化類)

  • 創(chuàng)建類實(shí)例(new Class)
  • 類或接口靜態(tài)變量的引用或賦值
  • 類靜態(tài)方法的調(diào)用
  • 反射加載(Class.forName(''))
  • 子類被初始化,其父類也會(huì)被初始化
  • jvm啟動(dòng)時(shí)被標(biāo)記啟動(dòng)類的類,或直接java.exe命令運(yùn)行指定類

演示代碼如下:

?/**
?*?定義父類與子類
?*/
?class?Parent?{
??public?static?int?a?=?10;
??static?{
???System.out.println("?父類初始化?");
??}
?}
?class?Children?extends?Parent{
??public?static?int?a?=?100;
??static?{
???System.out.println("?子類初始化?");
??}
?}
?public?static?void?main(String[]?args)?throws?Exception?{
??//?子類沒(méi)有定義變量a?(?public?static?int?a?=?100;)
????System.out.println(Children.a);?//?輸出?--??父類初始化?--?10?
????//?主動(dòng)調(diào)用時(shí)才會(huì)執(zhí)行類的靜態(tài)塊
????-----------------------------------------
????//?子類定義變量a?
????System.out.println(Children.a);?//?輸出?--?父類初始化?--?子類初始化??--?100?
??//?子類被初始化時(shí),優(yōu)先初始化父類,所以父類靜態(tài)塊執(zhí)行;調(diào)用變量a屬于子類定義,屬于主動(dòng)調(diào)用,所以子類靜態(tài)塊執(zhí)行
?}

調(diào)試輸出加載對(duì)象(VM options 中添加 -XX:+TraceClassLoading

  • [Loaded com.lgy.example.class_segregation.Parent from file:/E:/dataway-demo/example/target/classes/]
  • [Loaded com.lgy.example.class_segregation.Children from file:/E:/dataway-demo/example/target/classes/]

僅在首次主動(dòng)使用才會(huì)被初始化。

4、總結(jié)

以上就是關(guān)于自定義類加載器、加載過(guò)程的全部?jī)?nèi)容。

本文是針對(duì)于類隔離實(shí)現(xiàn)之自定義類加載器的擴(kuò)展,對(duì)于應(yīng)用中類加載階段的進(jìn)一步分析。

通過(guò)本文的分析可以了解到類加載過(guò)程及涉及到的jvm中的模塊,在整理過(guò)程中發(fā)現(xiàn)有些細(xì)節(jié)還需要擴(kuò)展,所以還尚未成功,還需持續(xù)跟進(jìn)。

到此這篇關(guān)于JVM分析之類加載機(jī)制詳解的文章就介紹到這了,更多相關(guān)JVM類加載機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot3整合Mybatis3的完整步驟記錄

    Springboot3整合Mybatis3的完整步驟記錄

    這篇文章主要給大家介紹了關(guān)于Springboot3整合Mybatis3的完整步驟,Spring Boot和MyBatis分別是兩個(gè)功能強(qiáng)大的框架,它們的協(xié)同使用可以極大地簡(jiǎn)化數(shù)據(jù)訪問(wèn)層的開發(fā),提高整體的開發(fā)效率,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • 如何使用mybatis-plus實(shí)現(xiàn)分頁(yè)查詢功能

    如何使用mybatis-plus實(shí)現(xiàn)分頁(yè)查詢功能

    最近在研究mybatis,然后就去找簡(jiǎn)化mybatis開發(fā)的工具,發(fā)現(xiàn)就有通用Mapper和mybatis-plus兩個(gè)比較好的可是使用,可是經(jīng)過(guò)對(duì)比發(fā)現(xiàn)還是mybatis-plus比較好,下面這篇文章主要給大家介紹了關(guān)于如何使用mybatis-plus實(shí)現(xiàn)分頁(yè)查詢功能的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • 深入解析Java中的編碼轉(zhuǎn)換以及編碼和解碼操作

    深入解析Java中的編碼轉(zhuǎn)換以及編碼和解碼操作

    這篇文章主要介紹了Java中的編碼轉(zhuǎn)換以及編碼和解碼操作,文中詳細(xì)解讀了編碼解碼的相關(guān)IO操作以及內(nèi)存使用方面的知識(shí),需要的朋友可以參考下
    2016-02-02
  • Java文件讀取寫入后 md5值不變的實(shí)現(xiàn)方法

    Java文件讀取寫入后 md5值不變的實(shí)現(xiàn)方法

    下面小編就為大家分享一篇Java文件讀取寫入后 md5值不變的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助
    2017-11-11
  • 全面詳解Maven打包及其相關(guān)插件和高級(jí)特性

    全面詳解Maven打包及其相關(guān)插件和高級(jí)特性

    這篇文章主要為大家介紹了Maven打包及其相關(guān)插件和高級(jí)特性的全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 一文搞懂MyBatis多數(shù)據(jù)源Starter實(shí)現(xiàn)

    一文搞懂MyBatis多數(shù)據(jù)源Starter實(shí)現(xiàn)

    本文將實(shí)現(xiàn)一個(gè)MyBatis的Springboot的Starter包,引用這個(gè)Starter包后,僅需要提供少量配置信息,就能夠完成MyBatis多數(shù)據(jù)源的初始化和使用,需要的小伙伴可以參考一下
    2023-04-04
  • springboot+redis過(guò)期事件監(jiān)聽(tīng)實(shí)現(xiàn)過(guò)程解析

    springboot+redis過(guò)期事件監(jiān)聽(tīng)實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了springboot+redis過(guò)期事件監(jiān)聽(tīng)實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 關(guān)于BufferedReader的讀取效率問(wèn)題

    關(guān)于BufferedReader的讀取效率問(wèn)題

    這篇文章主要介紹了關(guān)于BufferedReader的讀取效率問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java多線程回調(diào)方法實(shí)例解析

    Java多線程回調(diào)方法實(shí)例解析

    這篇文章主要介紹了Java多線程回調(diào)方法實(shí)例解析,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 詳解Elastic Search搜索引擎在SpringBoot中的實(shí)踐

    詳解Elastic Search搜索引擎在SpringBoot中的實(shí)踐

    本篇文章主要介紹了Elastic Search搜索引擎在SpringBoot中的實(shí)踐,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01

最新評(píng)論