您好,歡迎來(lái)到賦能網(wǎng)!

Java之JVM的相關(guān)介紹

賦能網(wǎng) 2023-05-10 86

    JVM的中文名稱叫java虛擬機(jī),它是由軟件技術(shù)模擬出計(jì)算機(jī)運(yùn)行的一個(gè)虛擬的計(jì)算機(jī)。JVM也充當(dāng)著一個(gè)翻譯官的角色,我們編寫出的Java程序,是不能夠被操作系統(tǒng)所直接識(shí)別的,這時(shí)候JVM的作用就體現(xiàn)出來(lái)了,它負(fù)責(zé)把我們的程序翻譯給系統(tǒng)“聽(tīng)”,告訴它我們的程序需要做什么操作。我們都知道Java的程序需要經(jīng)過(guò)編譯后,產(chǎn)生.Class文件,JVM才能識(shí)別并運(yùn)行它,JVM針對(duì)每個(gè)操作系統(tǒng)開(kāi)發(fā)其對(duì)應(yīng)的解釋器,所以只要其操作系統(tǒng)有對(duì)應(yīng)版本的JVM,那么這份Java編譯后的代碼就能夠運(yùn)行起來(lái),這就是Java能一次編譯,到處運(yùn)行的原因。

一、JVM的生命周期

    JVM在Java程序開(kāi)始執(zhí)行的時(shí)候,它才運(yùn)行,程序結(jié)束的時(shí)它就停止。一個(gè)Java程序會(huì)開(kāi)啟一個(gè)JVM進(jìn)程,如果一臺(tái)機(jī)器上運(yùn)行三個(gè)程序,那么就會(huì)有三個(gè)運(yùn)行中的JVM進(jìn)程。JVM中的線程分為兩種:守護(hù)線程和普通線程守護(hù)線程是JVM自己使用的線程,比如垃圾回收(GC)就是一個(gè)守護(hù)線程。普通線程一般是Java程序的線程,只要JVM中有普通線程在執(zhí)行,那么JVM就不會(huì)停止。權(quán)限足夠的話,可以調(diào)用exit()方法終止程序。

二、JVM的啟動(dòng)過(guò)程

1、JVM的裝入環(huán)境和配置

    在學(xué)習(xí)這個(gè)之前,我們需要了解一件事情,就是JDK和JRE的區(qū)別。JDK是面向開(kāi)發(fā)人員使用的SDK,它提供了Java的開(kāi)發(fā)環(huán)境和運(yùn)行環(huán)境,JDK中包含了JRE。JRE是Java的運(yùn)行環(huán)境,是面向所有Java程序的使用者,包括開(kāi)發(fā)者。JRE = 運(yùn)行環(huán)境 = JVM。如果安裝了JDK,會(huì)發(fā)現(xiàn)電腦中有兩套JRE,一套位于/Java/jre.../下,一套位于/Java/jdk.../jre下。那么問(wèn)題來(lái)了,一臺(tái)機(jī)器上有兩套以上JRE,誰(shuí)來(lái)決定運(yùn)行那一套呢?這個(gè)任務(wù)就落到j(luò)ava.exe身上,java.exe的任務(wù)就是找到合適的JRE來(lái)運(yùn)行java程序。

java.exe按照以下的順序來(lái)選擇JRE:

    自己目錄下有沒(méi)有JRE

    父目錄下有沒(méi)有JRE

    查詢注冊(cè)表: HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\"當(dāng)前JRE版本號(hào)"\JavaHome

這幾步的主要核心是為了找到JVM的絕對(duì)路徑。

    jvm.cfg的路徑為:JRE路徑\lib\"CPU架構(gòu)"\jvm.fig

jvm.cfg的內(nèi)容大致如下:

    -client KNOWN 
    -server KNOWN 
    -hotspot ALIASED_TO -client 
    -classic WARN 
    -native ERROR 
    -green ERROR 
KNOWN 表示存在 、IGNORE 表示不存在 、ALIASED_TO 表示給別的JVM去一個(gè)別名
WARN 表示不存在時(shí)找一個(gè)替代 、ERROR 表示不存在拋出異常
2、裝載JVM

    通過(guò)第一步找到JVM的路徑后,Java.exe通過(guò)LoadJavaVM來(lái)裝入JVM文件。
LoadLibrary裝載JVM動(dòng)態(tài)連接庫(kù),然后把JVM中的到處函數(shù)JNI_CreateJavaVM和JNI_GetDefaultJavaVMIntArgs 掛接到InvocationFunction 變量的CreateJavaVM和GetDafaultJavaVMInitArgs 函數(shù)指針變量上。JVM的裝載工作完成。
3、初始化JVM,獲得本地調(diào)用接口

    調(diào)用InvocationFunction -> CreateJavaVM也就是JVM中JNI_CreateJavaVM方法獲得JNIEnv結(jié)構(gòu)的實(shí)例。
4、運(yùn)行Java程序

    JVM運(yùn)行Java程序的方式有兩種:jar包 與 Class
    運(yùn)行jar 的時(shí)候,Java.exe調(diào)用GetMainClassName函數(shù),該函數(shù)先獲得JNIEnv實(shí)例然后調(diào)用JarFileJNIEnv類中g(shù)etManifest(),從其返回的Manifest對(duì)象中取getAttrebutes("Main-Class")的值,即jar 包中文件:meta-INF/MANIFEST.MF指定的的Main-Class的主類名作為運(yùn)行的主類。之后main函數(shù)會(huì)調(diào)用Java.c中LoadClass方法裝載該主類(使用JNIEnv實(shí)例的FindClass)。
    運(yùn)行Class的時(shí)候,main函數(shù)直接調(diào)用Java.c中的LoadClass方法裝載該類。

5、Class文件

    Class文件由Java編譯器生成,我們創(chuàng)建的.Java文件在經(jīng)過(guò)編譯器后,會(huì)變成.Class的文件,這樣才能被JVM所識(shí)別并運(yùn)行。

6、類加載子系統(tǒng)

類加載子系統(tǒng)也可以稱之為類加載器,JVM默認(rèn)提供三個(gè)類加載器:

    BootStrap ClassLoader :稱之為啟動(dòng)類加載器,是最頂層的類加載器,負(fù)責(zé)加載JDK中的核心類庫(kù),如 rt.jar、resources.jar、charsets.jar等。

    Extension ClassLoader:稱之為擴(kuò)展類加載器,負(fù)責(zé)加載Java的擴(kuò)展類庫(kù),默認(rèn)加載$JAVA_HOME中jre/lib/*.jar 或 -Djava.ext.dirs指定目錄下的jar包。

    App ClassLoader:稱之為系統(tǒng)類加載器,負(fù)責(zé)加載應(yīng)用程序classpath目錄下所有jar和class文件。

    除了Java默認(rèn)提供的三個(gè)ClassLoader(加載器)之外,我們還可以根據(jù)自身需要自定義ClassLoader,自定義ClassLoader必須繼承java.lang.ClassLoader 類。除了BootStrap ClassLoader 之外的另外兩個(gè)默認(rèn)加載器都是繼承自java.lang.ClassLoader 。BootStrap ClassLoader 不是一個(gè)普通的Java類,它底層由C++編寫,已嵌入到了JVM的內(nèi)核當(dāng)中,當(dāng)JVM啟動(dòng)后,BootStrap ClassLoader 也隨之啟動(dòng),負(fù)責(zé)加載完核心類庫(kù)后,并構(gòu)造Extension ClassLoader 和App ClassLoader 類加載器。

  想了解更多相關(guān)資訊請(qǐng)關(guān)注java培訓(xùn)頻道-查看更多,了解相關(guān)專業(yè)課程信息您可在線咨詢也可免費(fèi)申請(qǐng)?jiān)囌n。關(guān)注賦能網(wǎng)了解更多:4008-569-579

本文鏈接:

本文章“Java之JVM的相關(guān)介紹”已幫助 86 人

免責(zé)聲明:本信息由用戶發(fā)布,本站不承擔(dān)本信息引起的任何交易及知識(shí)產(chǎn)權(quán)侵權(quán)的法律責(zé)任!

本文由賦能網(wǎng) 整理發(fā)布。了解更多培訓(xùn)機(jī)構(gòu)》培訓(xùn)課程》學(xué)習(xí)資訊》課程優(yōu)惠》課程開(kāi)班》學(xué)校地址等機(jī)構(gòu)信息,可以留下您的聯(lián)系方式,讓課程老師跟你詳細(xì)解答:
咨詢熱線:4008-569-579

如果本頁(yè)不是您要找的課程,您也可以百度查找一下: