最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

概述java虛擬機(jī)中類(lèi)的加載器及類(lèi)加載過(guò)程

 更新時(shí)間:2021年04月15日 11:32:33   作者:丑B  
這篇文章主要介紹了概述java虛擬機(jī)中類(lèi)的加載器及類(lèi)加載過(guò)程,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下

1. 類(lèi)加載子系統(tǒng)

 1.1 概述

在這里插入圖片描述

類(lèi)加載子系統(tǒng)負(fù)責(zé)從文件系統(tǒng)或者網(wǎng)絡(luò)中加載Class文件,Class文件在文件開(kāi)頭有特定的文件標(biāo)識(shí)

在這里插入圖片描述

  • ClassLoader只負(fù)責(zé)class文件的加載,至于它是否可以運(yùn)行,則由Execution Engine 決定
  • 加載的類(lèi)信息存放于一塊成為 :方法區(qū)的內(nèi)存空間,除了類(lèi)的信息外,方法區(qū)中還會(huì)存放運(yùn)行時(shí)常量池信息,可能還包括字符串字面量和數(shù)字常量(這部分常量信息是Class文件中常量池部分的內(nèi)存映射)

在這里插入圖片描述

字節(jié)碼中的常量池加載到 方法區(qū) -----> 運(yùn)行時(shí)常量池信息

1.2 類(lèi)的加載器

在這里插入圖片描述

  • Class file(字節(jié)碼文件) 存在與本地磁盤(pán)上(硬盤(pán)),字節(jié)碼文件在執(zhí)行的時(shí)候是需要被加載到JVM的方法區(qū)中,再根據(jù)方法區(qū)中的這個(gè)類(lèi)對(duì)象實(shí)例化出n個(gè)一模一樣的實(shí)例
  • Class file 加載到JVM中,被稱(chēng)為DNA元數(shù)據(jù)模板,放在方法區(qū)。
  • 在Class文件 --> JVM -->最終成為元數(shù)據(jù)模板,此過(guò)程就要一個(gè)運(yùn)輸工具(類(lèi)加載器 Class Loader),扮演一個(gè)快遞員的角色。

2.類(lèi)的加載過(guò)程

2.1 類(lèi)的加載過(guò)程簡(jiǎn)圖

在這里插入圖片描述
在這里插入圖片描述

2.2 加載階段:Loading

  • 通過(guò)一個(gè)類(lèi)的全限定名獲取定義此類(lèi)的二進(jìn)制字節(jié)流
  • 將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
  • 在內(nèi)存中生成一個(gè)代表這個(gè)類(lèi)的java.lang.Class對(duì)象,作為方法區(qū)這個(gè)類(lèi)的各種數(shù)據(jù)的訪(fǎng)問(wèn)入口

小補(bǔ)充:加載字節(jié)碼文件(.class)的方式

  • 本地系統(tǒng)直接加載
  • 網(wǎng)絡(luò)獲?。篧eb Applet
  • jar、war包
  • 動(dòng)態(tài)代理:運(yùn)行時(shí)計(jì)算生成…

2.3 鏈接階段:Linking

驗(yàn)證(Verify)

  • 目的在于確保Class文件的字節(jié)流中包含信息符合當(dāng)前虛擬機(jī)要求,保證被加載類(lèi)的正確性,不會(huì)危害虛擬機(jī)自身安全
  • 主要包括四種驗(yàn)證:文件格式驗(yàn)證、元數(shù)據(jù)驗(yàn)證、字節(jié)碼驗(yàn)證、符號(hào)引用驗(yàn)證

準(zhǔn)備(Prepare)

  • 為類(lèi)變量分配內(nèi)存并且設(shè)置該類(lèi)變量的默認(rèn)初始值,即“零值”

在這里插入圖片描述

(在準(zhǔn)備階段 a = 0,到下一個(gè)階段(初始化階段)a = 1)
(不同的數(shù)據(jù)類(lèi)型的變量默認(rèn)值不一樣,如 int =0 ,引用類(lèi)型 = null)

  • 這里不包含用final 修飾的static,因?yàn)閒inal 在編譯的時(shí)候就會(huì)分配了,準(zhǔn)備階段會(huì)顯示初始化(final修飾的變量是:常量)
  • 這里不會(huì)為實(shí)例變量分配初始化,類(lèi)變量會(huì)分配在方法區(qū)中,而實(shí)例變量是會(huì)隨著對(duì)象一起分配到Java堆中

解析(Resolve)

  • 將常量池內(nèi)的符號(hào)引用轉(zhuǎn)換為直接引用的過(guò)程
  • 事實(shí)上,解析操作往往會(huì)伴隨著JVM在執(zhí)行完初始化之后再執(zhí)行
  • 符號(hào)引用:一組符號(hào)來(lái)描述所引用的目標(biāo)。符號(hào)引用的字面量形式明確定義在《Java 虛擬機(jī)規(guī)范》的Class 文件格式中
  • 直接引用:直接指向目標(biāo)的指針、相對(duì)偏移量或者一個(gè)間接定位到目標(biāo)的句柄
  • 解析動(dòng)作主要針對(duì)類(lèi)或接口、字段、類(lèi)方法、接口方法、方法類(lèi)型等。對(duì)應(yīng)常量池中的CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info等。

2.4 初始化階段:initialization

  • 初始化階段就是執(zhí)行類(lèi)構(gòu)造器方法 clinit()的過(guò)程,此方法不需要定義,是javac 編譯器自動(dòng)收集類(lèi)中的所有了變量的賦值動(dòng)作和靜態(tài)代碼塊中的語(yǔ)句合并而來(lái)

例子1:

public class Test {
    private static int a=2;
    private static int b=20;

    public static void main(String[] args) {
        System.out.println(a);
        System.out.println(b);
    }
}

在這里插入圖片描述

例子2:

public class Test {
    public static void main(String[] args) {
        System.out.println("測(cè)試一下");
    }
}

在這里插入圖片描述

  • 構(gòu)造器方法中指令按語(yǔ)句在源文件中出現(xiàn)的順序執(zhí)行
  • clinit() 方法不同于類(lèi)的構(gòu)造器。(關(guān)聯(lián):構(gòu)造器是虛擬機(jī)視角下的 init())
  • 若該類(lèi)具有父類(lèi),JVM會(huì)保證子類(lèi)的 clinit () 執(zhí)行前,父類(lèi)的 clinit () 已經(jīng)執(zhí)行完畢
  • 虛擬機(jī)必須保證一個(gè)類(lèi)的 clinit () 方法在多線(xiàn)程下被同步加鎖,虛擬機(jī)只會(huì)調(diào)用一次 clinit 方法,保證類(lèi)只被加載一次

3.幾種類(lèi)的加載器

  • JVM支持兩種類(lèi)型的類(lèi)加載器,分別為引導(dǎo)類(lèi)加載器(Bootstrap ClassLoader)和 自定義類(lèi)加載器(User-Defined ClassLoader)
  • 從概念上來(lái)講,自定義類(lèi)加載器一般指的是程序中由開(kāi)發(fā)人員自定義的一類(lèi)類(lèi)加載器,但是Java虛擬機(jī)規(guī)范并沒(méi)有這么定義,而是將所有派生于抽象類(lèi)ClassLoader的類(lèi)加載器都劃分為自定義類(lèi)加載器(除了Bootstrap ClassLoader其他的都為 自定義類(lèi)加載器)
  • 無(wú)論類(lèi)加載器的類(lèi)型如何劃分,在程序中,我們最常見(jiàn)的類(lèi)加載器始終只有3個(gè),如下所示:

在這里插入圖片描述

代碼:

public class Test {

    public static void main(String[] args) {
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2 :應(yīng)用類(lèi)加載器
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);//sun.misc.Launcher$ExtClassLoader@34a245ab :擴(kuò)展類(lèi)加載器
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);//null :引導(dǎo)類(lèi)加載器:非Java語(yǔ)言實(shí)現(xiàn)

        ClassLoader classLoader = Test.class.getClassLoader();
        System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
        
         ClassLoader classLoader1 = String.class.getClassLoader();
        System.out.println(classLoader1);//null
    }
}

3.1 引導(dǎo)類(lèi)加載器:

  • BootstrapClassLoader 這個(gè)類(lèi)加載器使用 C/C++語(yǔ)言實(shí)現(xiàn),嵌套在JVM內(nèi)部
  • 它用來(lái)加載Java 的核心類(lèi)庫(kù)(JAVA_HOME/jre/lib/rt.jar、resources.jar 或 sun.boot.class.path路徑下的內(nèi)容),用于提供JVM自身需要的類(lèi)
  • 并不繼承自 java.lang.ClassLoader ,沒(méi)有父類(lèi)加載器
  • 加載擴(kuò)展類(lèi)和應(yīng)用程序類(lèi)加載器,并指定為他們的父類(lèi)加載器
  • 出于安全考慮,Bootstrap 啟動(dòng)類(lèi)加載器只加載包名為 java 、javax、sun等開(kāi)頭的類(lèi)

3.2 擴(kuò)展類(lèi)加載器:ExtensionClassLoader

  • Java 語(yǔ)言編寫(xiě),派生于ClassLoader類(lèi)
  • 父類(lèi)加載器為:?jiǎn)?dòng)類(lèi)加載器
  • 從 java.ext.dirs系統(tǒng)屬性所指定的目錄中加載類(lèi)庫(kù),或從JDK的安裝目錄的jre/lib/ext子目錄(擴(kuò)展目錄)下加載類(lèi)庫(kù),如果用戶(hù)創(chuàng)建的jar包放在此目錄下,也會(huì)自動(dòng)由擴(kuò)展類(lèi)加載器進(jìn)行加載

3.3 應(yīng)用程序類(lèi)加載器:AppClassLoader

  •  java語(yǔ)言編寫(xiě),派生于 ClassLoader
  • 父類(lèi)加載器為 ExtensionClassLoader
  • 負(fù)責(zé)加載環(huán)境變量classpath或者系統(tǒng)屬性 java.class.path 指定路徑下的類(lèi)庫(kù)
  • 該類(lèi)加載器是程序中默認(rèn)的類(lèi)加載器,一般來(lái)說(shuō),Java應(yīng)用的類(lèi)都是由它來(lái)完成加載
  • 通過(guò)ClassLoader # getSystemClassLoader()方法可以獲取到該類(lèi)加載器

3.4 用戶(hù)自定義類(lèi)加載器

  • 在Java 的日常應(yīng)用程序開(kāi)發(fā)中,類(lèi)的加載幾乎是由上述3種類(lèi)加載器相互配合執(zhí)行的,在必要的時(shí)候,我們還可以自定義類(lèi)加載器,來(lái)定制類(lèi)的加載方式

為什么要用自定義類(lèi)加載器呢?

  • 隔離加載類(lèi)
  • 修改類(lèi)加載的方式
  • 擴(kuò)展加載源
  • 防止源碼泄漏

用戶(hù)自定義類(lèi)加載器實(shí)現(xiàn)步驟

  • 通過(guò)繼承抽象類(lèi) java.lang.ClassLoader 類(lèi)的方式,實(shí)現(xiàn)自己的類(lèi)加載器,以滿(mǎn)足一些特殊的需求
  • JDK1.2之前,總會(huì)去繼承ClassLoader類(lèi)并重寫(xiě)loadClass()方法,從而實(shí)現(xiàn)自定義的類(lèi)加載器,但是在JDK1.2之后,已不再建議去覆蓋loadClass()方法,而是建議把自定義的類(lèi)加載邏輯寫(xiě)在 findClass()方法中
  • 如果對(duì)于類(lèi)加載器沒(méi)有太過(guò)于復(fù)雜的需求,可以通過(guò)直接繼承 URLClassLoader類(lèi),這樣就可以避免自己去編寫(xiě)findClass()方法及其獲取字節(jié)碼流的方式,使自定義類(lèi)加載器編寫(xiě)更加簡(jiǎn)潔

在這里插入圖片描述

繼承體系


在這里插入圖片描述

獲取 ClassLoader


在這里插入圖片描述

4.雙親委派機(jī)制

Java 虛擬機(jī)對(duì)class文件采用的是按需加載的方式,也就是說(shuō)當(dāng)需要使用該類(lèi)時(shí)才會(huì)將它的class文件加載到內(nèi)存生成class對(duì)象。而且加載某個(gè)類(lèi)的class文件時(shí),Java虛擬機(jī)采用的雙親委派模式,即把請(qǐng)求交由父類(lèi)處理,它是一種任務(wù)委派模式

在這里插入圖片描述

  • 如果一個(gè)類(lèi)加載器收到了類(lèi)的加載請(qǐng)求,它并不會(huì)自己先去加載,而是把這個(gè)請(qǐng)求委托給父類(lèi)的加載器去執(zhí)行
  • 如果父類(lèi)加載器還存在其父類(lèi)加載器,則進(jìn)一步向上委托,依次遞歸請(qǐng)求最終將到達(dá)頂層的啟動(dòng)類(lèi)加載器
  • 如果類(lèi)加載器可以完成類(lèi)加載任務(wù),就成功返回,如果父類(lèi)加載器無(wú)法完成此加載任務(wù),子類(lèi)加載器才會(huì)嘗試去加載,這就是雙親委派模式

優(yōu)勢(shì)

  • 避免類(lèi)的重復(fù)加載
  • 保護(hù)程序安全,防止核心API被隨意篡改:自定義:java.lang.String …
  • 不要亂取包名

5.其他

在JVM中表示兩個(gè)class對(duì)象是否為同一個(gè)類(lèi)存在兩個(gè)必要條件

  • 類(lèi)的全限定類(lèi)名必須一致,包括包名
  • 加載這個(gè)類(lèi)的ClassLoader(指ClassLoader實(shí)例對(duì)象)必須相同
  • 即使兩個(gè)類(lèi)來(lái)源于同一個(gè)文件,但是類(lèi)加載器不一樣,那這兩個(gè)類(lèi)對(duì)象也是不相等的

到此這篇關(guān)于概述java虛擬機(jī)中類(lèi)的加載器及類(lèi)加載過(guò)程的文章就介紹到這了,更多相關(guān)Jvm中類(lèi)的加載器及類(lèi)加載過(guò)程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 讀取文本指定的某一行內(nèi)容的方法

    Java 讀取文本指定的某一行內(nèi)容的方法

    今天小編就為大家分享一篇Java 讀取文本指定的某一行內(nèi)容的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Spring Boot結(jié)合IDEA自帶Maven插件如何快速切換profile

    Spring Boot結(jié)合IDEA自帶Maven插件如何快速切換profile

    IDEA是目前 Java 開(kāi)發(fā)者中使用最多的開(kāi)發(fā)工具,它有著簡(jiǎn)約的設(shè)計(jì)風(fēng)格,強(qiáng)大的集成工具,便利的快捷鍵,這篇文章主要介紹了Spring Boot結(jié)合IDEA自帶Maven插件快速切換profile,需要的朋友可以參考下
    2023-03-03
  • Java中static靜態(tài)變量的初始化完全解析

    Java中static靜態(tài)變量的初始化完全解析

    static所聲明的變量在Java中有一個(gè)初始化的先后順序,帶著這個(gè)問(wèn)題接下來(lái)我們就來(lái)進(jìn)行Java中static靜態(tài)變量的初始化完全解析:
    2016-06-06
  • JAVA?module-info.java文件詳解

    JAVA?module-info.java文件詳解

    這篇文章主要介紹了JAVA?module-info.java文件詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java中如何執(zhí)行多條shell/bat命令

    Java中如何執(zhí)行多條shell/bat命令

    這篇文章主要介紹了Java中如何執(zhí)行多條shell/bat命令的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Spring?Boot?使用斷言讓你的代碼在上線(xiàn)前就通過(guò)“體檢”(最新整理)

    Spring?Boot?使用斷言讓你的代碼在上線(xiàn)前就通過(guò)“體檢”(最新整理)

    斷言是一種編程技巧,用于在代碼中插入檢查點(diǎn),驗(yàn)證程序的狀態(tài)是否符合預(yù)期,如果斷言失敗,程序會(huì)拋出一個(gè)錯(cuò)誤,幫助你快速發(fā)現(xiàn)和修復(fù)bug,本文給大家介紹Spring?Boot?斷言:讓你的代碼在上線(xiàn)前就通過(guò)“體檢”,感興趣的朋友一起看看吧
    2025-03-03
  • 關(guān)于RestTemplate中的Get請(qǐng)求

    關(guān)于RestTemplate中的Get請(qǐng)求

    這篇文章主要介紹了關(guān)于RestTemplate中的Get請(qǐng)求,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • MyBatis-Plus 批量插入數(shù)據(jù)的操作方法

    MyBatis-Plus 批量插入數(shù)據(jù)的操作方法

    spring boot+mybatis plus環(huán)境,單條插入用的是BaseMapper自帶的insert方法,本文重點(diǎn)給大家介紹MyBatis-Plus 批量插入數(shù)據(jù)的操作方法,感興趣的朋友一起看看吧
    2021-09-09
  • 基于Mybatis-Plus的CRUD的實(shí)現(xiàn)

    基于Mybatis-Plus的CRUD的實(shí)現(xiàn)

    這篇文章主要介紹了基于Mybatis-Plus的CRUD的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Springboot 整合 Java DL4J 實(shí)現(xiàn)醫(yī)學(xué)影像診斷功能介紹

    Springboot 整合 Java DL4J 實(shí)現(xiàn)醫(yī)學(xué)影像診斷功能介紹

    本文介紹如何利用SpringBoot整合Java Deeplearning4j實(shí)現(xiàn)醫(yī)學(xué)影像診斷功能,重點(diǎn)介紹了卷積神經(jīng)網(wǎng)絡(luò)在處理醫(yī)學(xué)影像中的應(yīng)用,以及如何進(jìn)行數(shù)據(jù)預(yù)處理、模型構(gòu)建、訓(xùn)練與預(yù)測(cè),提供了詳細(xì)的代碼實(shí)現(xiàn)和單元測(cè)試方法,目的是輔助醫(yī)生更準(zhǔn)確快速地進(jìn)行疾病診斷
    2024-10-10

最新評(píng)論

大洼县| 木兰县| 郸城县| 黄山市| 策勒县| 芦溪县| 邵阳县| 若尔盖县| 盐亭县| 峨眉山市| 永清县| 化德县| 德惠市| 郑州市| 宿松县| 通州区| 榆林市| 渝中区| 黔江区| 铁力市| 裕民县| 曲水县| 红原县| 佛山市| 昔阳县| 夹江县| 呼和浩特市| 巴中市| 大余县| 西吉县| 晋宁县| 河间市| 仁寿县| 曲沃县| 恩平市| 浦江县| 营山县| 威宁| 舟山市| 丰顺县| 神池县|