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

JVM加載class文件的原理機(jī)制實(shí)例詳解

 更新時(shí)間:2022年04月28日 14:29:35   作者:m0_67401606  
Java是一種具有動(dòng)態(tài)性的解釋型語言,類(class)只有被加載到JVM后才能運(yùn)行,接下來通過本文給大家介紹JVM加載class文件的原理機(jī)制詳解,感興趣的朋友一起看看吧

一、JVM簡(jiǎn)介

JVM是Java Virtual Machine(Java虛擬機(jī))的縮寫,JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來的計(jì)算機(jī),是通過在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來實(shí)現(xiàn)的。

Java語言的一個(gè)非常重要的特點(diǎn)就是與平臺(tái)的 無關(guān)性。而使用Java虛擬機(jī)是實(shí)現(xiàn)這一特點(diǎn)的關(guān)鍵。一般的高級(jí)語言如果要在不同的平臺(tái)上運(yùn)行,至少需要編譯成不同的目標(biāo)代碼。而引入Java語言虛擬機(jī)后,Java語言在不同平臺(tái)上運(yùn)行時(shí)不需要重新編譯。Java語言使用Java虛擬機(jī)屏蔽了與平臺(tái)相關(guān)的信息,使得Java語言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改的運(yùn)行。Java虛擬機(jī)在執(zhí)行字節(jié)碼時(shí),把字節(jié)碼解釋成具體平臺(tái)上的及其指令執(zhí)行。這就是Java能夠“一次編譯,到處運(yùn)行”的原因。

二、JVM的組成部分

由圖可以看出,JVM是運(yùn)行在操作系統(tǒng)之上的,它與硬件沒有直接的交互。

JVM的組成

1. 類加載器 Class Loader

類加載器的作用是加載類文件到內(nèi)存,比如編寫一個(gè)HelloWorld.java程序,然后通過javac編譯生成class文件。由Class Loader將class文件加載到內(nèi)存中。但是Class Loader加載class文件有格式要求。
注意:Class Loader只管加載,只要符合文件結(jié)構(gòu)就加載,至于能不能運(yùn)行,是由Execution Engine負(fù)責(zé)。
2. 執(zhí)行引擎 Exexution Engine
執(zhí)行引擎也叫作解釋器,負(fù)責(zé)解釋命令,提交操作系統(tǒng)執(zhí)行。
3. 本地接口 Native Interface
本地接口的作用是為了融合不同的編程語言為Java所用。它的初衷是為了融合C/C++程序,Java誕生的時(shí)候是C/C++橫行的時(shí)候,要想立足,必須要有一個(gè)聰明的、睿智的調(diào)用C/C++程序,于是就在內(nèi)存中專門開辟了一塊區(qū)域處理標(biāo)記為native的代碼,它的具體做法是Native Method Stack中登記native方法,在Execution Engine執(zhí)行時(shí)加載加載native libraries。目前該方法只有在與硬件有關(guān)的應(yīng)用中才會(huì)使用,在企業(yè)級(jí)應(yīng)用中已經(jīng)比較少見,因?yàn)楝F(xiàn)在的異構(gòu)領(lǐng)域間的通信很發(fā)達(dá),比如可以使用Socket通信,也可以使用WebService等。
4. 運(yùn)行數(shù)據(jù)區(qū) Runtime data area
運(yùn)行數(shù)據(jù)區(qū)使整個(gè)JVM的重點(diǎn)。我們所寫的程序都被加載到這里,之后才開始運(yùn)行,Java生態(tài)系統(tǒng)如此的繁榮,得益于該區(qū)域的優(yōu)良自治。

三、JVM加載class文件的原理機(jī)制

1. Java中的所有類,必須被裝載到JVM中才能運(yùn)行,這個(gè)裝載工作是由JVM中的類裝載器完成的,類裝載器所做的工作實(shí)質(zhì)是把類文件從硬盤讀取到內(nèi)存中,作用就是在運(yùn)行時(shí)加載類。
Java類加載器基于三個(gè)機(jī)制:委托、可見性和單一性。
(1)委托機(jī)制是指加載一個(gè)類的請(qǐng)求交給父類加載器,如果這個(gè)父類加載器不能夠找到或加載這個(gè)類,那么再加載它。
(2)可見性的原理是子類的加載器可以看見所有的父類加載器加載的類,而父類加載器看不到子類加載器加載的類。
(3)單一性原理是指一個(gè)類僅被加載一次,這是由委托機(jī)制確保子類加載器不會(huì)再次加載父類加載器加載過的類。
2. Java中的類大致分為三種:
(1)系統(tǒng)類
(2)擴(kuò)展類
(3)由程序員自定義的類
3. 類裝載有兩種方式
(1)隱式裝載:
程序在運(yùn)行過程中當(dāng)碰到通過new等方式生成類或者子類對(duì)象、使用類或者子類的靜態(tài)域時(shí),隱式調(diào)用類加載器加載對(duì)應(yīng)的的類到JVM中。
(2)顯式裝載:
通過調(diào)用Class.forName()或者ClassLoader.loadClass(className)等方法,顯式加載需要的類。
4. 類加載的動(dòng)態(tài)性體現(xiàn)
一個(gè)應(yīng)用程序總是由n多個(gè)類組成,Java程序啟動(dòng)時(shí),并不是一次把所有的類全部加載再運(yùn)行,他總是把保證程序運(yùn)行的基礎(chǔ)類一次性加載到JVM中,其他類等到JVM用到的時(shí)候再加載,這樣是為了節(jié)省內(nèi)存的開銷,因?yàn)镴ava最早就是為嵌入式系統(tǒng)而設(shè)計(jì)的,內(nèi)存寶貴,而用到時(shí)再加載這也是Java動(dòng)態(tài)性的一種體現(xiàn)。
5. Java類加載器
Java中的類加載器實(shí)質(zhì)上也是也是類,功能是把類加載入JVM中,值得注意的是JVM的類加載器有三個(gè),原因有:一方面是為了分工明確,各自負(fù)責(zé)各自的區(qū)塊,另一方面為了實(shí)現(xiàn)委托模型。
層次結(jié)構(gòu)如下:
BootStrap Loader(引導(dǎo)類加載器) ----- 負(fù)責(zé)加載系統(tǒng)類

ExtClassLoader(擴(kuò)展類加載器) ----- 負(fù)責(zé)加載擴(kuò)展類
AppClassLoade(應(yīng)用類加載器)r ----- 負(fù)責(zé)加載應(yīng)用類
6. 類加載器之間如何協(xié)調(diào)工作的
Java中有三個(gè)類加載器,碰到一個(gè)類需要加載時(shí),Java采用委托模型機(jī)制來協(xié)調(diào)和區(qū)分該由哪個(gè)類加載器完成。簡(jiǎn)單來說就是,“類裝載器有載入類的需求時(shí),會(huì)先請(qǐng)示其Parent使用其搜索路徑幫忙載入”,如果Parent找不到,那么才由自己依照自己的搜索路徑搜索類。
實(shí)例一:

package ClassLoaderTest;
public class ClassLoaderTest {
    public static void main(String[] args) {
        ClassLoader c1 = ClassLoaderTest.class.getClassLoader();
        System.out.println(c1);
        ClassLoader c1Parent = c1.getParent();
        System.out.println(c1Parent);
        ClassLoader c1Root = c1Parent.getParent();
        System.out.println(c1Root);
    }
}

執(zhí)行結(jié)果:

在這里插入圖片描述

可以看出ClassLoaderTest是由AppClassLoader加載器加載的。AppClassLoader的Parent加載器是ExtClassLoader。但是ExtClassLoader的Parent是null,在Java中是無法獲取的。
實(shí)例二:

public class Test2 {
    public void test(){
        System.out.println(Test2.class);
        System.out.println(this.getClass());
        System.out.println(Test2.class.getClassLoader());
    }
}
public class Test1 {
    public static void main(String[] args) {
        System.out.println(Test1.class.getClassLoader());
        Test2 test2 = new Test2();
        test2.test();
    }
}

執(zhí)行結(jié)果:

在這里插入圖片描述

7. 預(yù)先加載和依需求加載
Java運(yùn)行環(huán)境為了優(yōu)化系統(tǒng),提高程序的執(zhí)行速度,在JRE運(yùn)行的開始會(huì)將Java運(yùn)行所需要的基本類采用預(yù)先加載(pre-loading)的方法全部加載到內(nèi)存當(dāng)中,因?yàn)檫@些單元在Java程序運(yùn)行的過程當(dāng)中要經(jīng)常使用的,主要包括JRE的rt.jar文件里面所有的.class文件。
當(dāng)java.exe虛擬機(jī)開始運(yùn)行以后,它會(huì)找到安裝在機(jī)器上的JRE環(huán)境,然后把控制權(quán)交給JRE,JRE的類加載器會(huì)自動(dòng)將lib目錄下的rt.jar基礎(chǔ)類別文件庫加載進(jìn)內(nèi)存,這些文件是Java程序執(zhí)行所必需的,所以系統(tǒng)在開始就將這些文件加載,避免以后的多次IO操作,從而提高程序執(zhí)行效率。然而我們?cè)诔绦蛑行枰褂米远x的類的時(shí)候就要使用依需求加載(load-on-demand)的方式,就是在Java程序需要用到的時(shí)候再加載,以減少內(nèi)存的消耗。
8. ClassLoader中一些 重要的方法

在這里插入圖片描述

9.什么地方適用類加載器
最經(jīng)典的例子就是AppletClassLoader,他被用來加載Applet使用的類,而Applet大部分是在網(wǎng)上使用,而非本地的操作系統(tǒng)使用。使用不同的類加載器,你可以從不同的源地址加載同一個(gè)類,它們被視為不同的類。J2EE使用多個(gè)類加載器加載不同地方的類,例如War文件由Web-app類加載器加載,而EJB-JAR中的類由另外的類加載器加載。有些服務(wù)器也支持熱部署,這是由類加載器實(shí)現(xiàn)。你也可以使用類加載器來加載數(shù)據(jù)庫或者其他持久層的數(shù)據(jù)。
10. 類加載器的階層體系
Java類加載器的工作原理:
當(dāng)執(zhí)行Java的.class文件的時(shí)候,java.exe會(huì)幫助我們找到j(luò)RE,接著找到JRE內(nèi)部的jcm.dll,這才是真正的Java虛擬機(jī)器,最后加載動(dòng)態(tài)庫,激活Java虛擬機(jī)器。虛擬機(jī)激活以后,會(huì)先做一些初始化的動(dòng)作,比如說讀取系統(tǒng)參數(shù)等。一旦初始化動(dòng)作完成后,就會(huì)產(chǎn)生第一個(gè)類加載器-----Bootstrap Loader,Bootstrap Loader是由C++撰寫而成,這個(gè)Bootstrap所做的初始工作中,除了一些基本的初始化動(dòng)作之外,最重要的就是加載Launcher.java之中的ExtClassLoader,并設(shè)定其parent為null,代表其父加載器為BootstrapLoader。然后Bootstrap loader再要求加載Launcher.java之中的AppClassLoader,并設(shè)定其parent為之前產(chǎn)生的ExtClassLoader實(shí)體。這兩個(gè)類加載器都是以靜態(tài)類的形式存在的。注意:Launcher E x t C l a s s L o a d e r . c l a s s 與 L a u n c h e r ExtClassLoader.class與Launcher ExtClassLoader.class與LauncherAppClassLoader.class都是由Bootstrap Loader所加載,所以Parent和由哪個(gè)類加載器加載沒有關(guān)系。
三者之間的關(guān)系:
Bootstrap Loader <—(extends)-----ExtClassLoader <—(extends)—AppClassLoader
這三個(gè)類加載器構(gòu)成了Java的類加載體系。它們分別從以下的路徑尋找程序所需要的類:
Bootstrap Loader:sun.boot.class.path
ExtClassLoader:java.ext.dirs
AppClassLoader:java.class.path
這三個(gè)參數(shù)可以通過System.getProperty()函數(shù)得到具體對(duì)應(yīng)的路徑。

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

相關(guān)文章

  • JAVA  靜態(tài)的單例的實(shí)例詳解

    JAVA 靜態(tài)的單例的實(shí)例詳解

    這篇文章主要介紹了JAVA 靜態(tài)的單例的實(shí)例詳解的相關(guān)資料,這里提供了實(shí)例方法,來說名不僅實(shí)現(xiàn)了延遲加載,又可以保證線程安全,不影響系統(tǒng)性能,需要的朋友可以參考下
    2017-07-07
  • Java日期格式化的實(shí)現(xiàn)(@JsonFormat和@JSONField)

    Java日期格式化的實(shí)現(xiàn)(@JsonFormat和@JSONField)

    本文主要介紹了Java日期格式化的實(shí)現(xiàn),主要介紹了@JsonFormat和@JSONField兩種方式,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • Java數(shù)據(jù)庫連接池的幾種配置方法(以MySQL數(shù)據(jù)庫為例)

    Java數(shù)據(jù)庫連接池的幾種配置方法(以MySQL數(shù)據(jù)庫為例)

    這篇文章主要介紹了Java數(shù)據(jù)庫連接池的幾種配置方法(以MySQL數(shù)據(jù)庫為例) 的相關(guān)資料,需要的朋友可以參考下
    2016-07-07
  • MapStruct表達(dá)式應(yīng)用及避坑詳解

    MapStruct表達(dá)式應(yīng)用及避坑詳解

    一不小心踩了MapStruct表達(dá)式的坑,發(fā)現(xiàn)了一個(gè)在官方文檔上都找不到的功能,有必要記錄下。MapStruct是一個(gè)代碼生成器,它基于約定優(yōu)于配置的方法大大簡(jiǎn)化了Java?Bean類型之間的映射的實(shí)現(xiàn)
    2022-02-02
  • spring中定時(shí)任務(wù)taskScheduler的詳細(xì)介紹

    spring中定時(shí)任務(wù)taskScheduler的詳細(xì)介紹

    這篇文章主要介紹了spring中定時(shí)任務(wù)taskScheduler的相關(guān)資料,文中通過示例代碼介紹的很詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來一起看看吧。
    2017-02-02
  • 淺談Java線程Thread.join方法解析

    淺談Java線程Thread.join方法解析

    本篇文章主要介紹了淺談Java線程Thread.join方法解析,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • Mybatis-Plus中分頁插件PaginationInterceptor的使用

    Mybatis-Plus中分頁插件PaginationInterceptor的使用

    我們?cè)陂_發(fā)的過程中,經(jīng)常會(huì)遇到分頁操作,本文主要介紹了Mybatis-Plus中分頁插件PaginationInterceptor的使用,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Java使用DualPivotQuicksort排序

    Java使用DualPivotQuicksort排序

    這篇文章主要介紹了Java使用DualPivotQuicksort排序,喜歡算法的同學(xué)一定要看一下
    2021-04-04
  • Java多線程(單例模式,阻塞隊(duì)列,定時(shí)器,線程池)詳解

    Java多線程(單例模式,阻塞隊(duì)列,定時(shí)器,線程池)詳解

    本文是多線程初級(jí)入門,主要介紹了多線程單例模式、阻塞隊(duì)列、定時(shí)器、線程池、多線程面試考點(diǎn),感興趣的小伙伴可以跟隨小編一起了解一下
    2022-09-09
  • SpringBoot項(xiàng)目使用validated實(shí)現(xiàn)參數(shù)校驗(yàn)框架

    SpringBoot項(xiàng)目使用validated實(shí)現(xiàn)參數(shù)校驗(yàn)框架

    當(dāng)談到Spring的參數(shù)校驗(yàn)功能時(shí),@Validated注解無疑是一個(gè)重要的利器,它為我們提供了一種簡(jiǎn)單而又強(qiáng)大的方式來驗(yàn)證請(qǐng)求參數(shù)的合法性,保證了系統(tǒng)的穩(wěn)定性和安全性,本文將介紹Spring Validated的基本用法以及在實(shí)際項(xiàng)目中的應(yīng)用,需要的朋友可以參考下
    2024-05-05

最新評(píng)論

房产| 阳原县| 花莲县| 巴彦县| 宣城市| 龙陵县| 新宾| 南陵县| 扬中市| 辽中县| 高邑县| 广饶县| 通化县| 屏东市| 营山县| 佛教| 奉新县| 普安县| 杭州市| 贵南县| 连州市| 乐业县| 礼泉县| 翁源县| 德清县| 博客| 肇州县| 灵台县| 天水市| 靖远县| 资源县| 上饶县| 临猗县| 湖北省| 隆林| 隆尧县| 衡东县| 江华| 玛沁县| 都江堰市| 耒阳市|