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

Java虛擬機啟動過程探索

 更新時間:2022年05月27日 14:18:17   作者:Java知識圖譜  
當我們在編寫Java應(yīng)用的時候,很少會注意Java程序是如何被運行的,如何被操作系統(tǒng)管理和調(diào)度的,帶著好奇心,探索一下Java虛擬機啟動過程

一、序言

當我們在編寫Java應(yīng)用的時候,很少會注意Java程序是如何被運行的,如何被操作系統(tǒng)管理和調(diào)度的。帶著好奇心,探索一下Java虛擬機啟動過程。

1、素材準備

Java源代碼、Java字節(jié)碼Java虛擬機、操作系統(tǒng)四個角度分解啟動過程。

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("HelloWorld!");
    }
}

2、源代碼生成字節(jié)碼

利用Java環(huán)境提供的可執(zhí)行命令javac將源代碼編譯成字節(jié)碼文件,編譯后的字節(jié)碼文件與平臺無關(guān),可跨平臺運行。注意區(qū)分javac命令是一個獨立的編譯應(yīng)用,源代碼編譯完成,進程終止。java命令啟動的虛擬機進程的編譯過程是將字節(jié)碼指令編譯成匯編指令(二進制指令)。

3、虛擬機解析字節(jié)碼

Java字節(jié)碼無法直接在操作系統(tǒng)上創(chuàng)建進程,因此需要借助已經(jīng)啟動的虛擬機進程來解析字節(jié)碼,處理字節(jié)碼有兩種常見方式:解釋型編譯型。

在命令行中每運行java命令代表啟動一個Java虛擬機進程,各虛擬機相互獨立,通過命令行參數(shù)分別對虛擬機進程進行配置。

Java虛擬機準備啟動完畢后,便可以依次解析字節(jié)碼指令,正式運行Java代碼部分。

4、操作系統(tǒng)管理虛擬機

操作系統(tǒng)通過進程管理和調(diào)度Java虛擬機,無法感知虛擬機間接解析Java字節(jié)碼部分。Java字節(jié)碼通過虛擬機的抽象,完成了在操作系統(tǒng)上運行。

二、Java虛擬機

當運行Java應(yīng)用時,需要先安裝Java環(huán)境,然而安裝的Java環(huán)境與Java應(yīng)用有什么關(guān)系,Java應(yīng)用是如何運行起來的,下面一探究竟。

二進制可執(zhí)行程序${JAVA_HOME}/bin/java是C++編寫經(jīng)過GCC編譯器編譯后形成的,探索Java虛擬機的運行原理,首先需要找到相應(yīng)的源碼。

當在安裝Java環(huán)境時,會看到一個src.zip壓縮文件,解壓后里面launcher/java.c文件便是可執(zhí)行文件java命令的主要源碼。

虛擬機的啟動入口位于launcher/java.cmain方法,整個流程分為如下幾個步驟: 配置JVM裝載環(huán)境;解析虛擬機參數(shù);設(shè)置線程棧大?。粓?zhí)行Java main方法

(一)配置JVM裝載環(huán)境

從操作系統(tǒng)加載環(huán)境變量、硬件信息等運行環(huán)境信息,為后續(xù)創(chuàng)建JVM進程做準備。

(二)命令行參數(shù)解析

裝載完JVM環(huán)境之后,需要對啟動時命令行參數(shù)進行解析,該過程通過ParseArguments方法實現(xiàn),并調(diào)用AddOption方法將解析完成的參數(shù)保存到JavaVMOption中。

比如常見的JavaVMOption參數(shù)在此步驟解析:

-Xms:設(shè)置堆的初始值InitialHeapSize,也是堆的最小值; 
-Xmx:設(shè)置堆的最大值MaxHeapSize;

JVM調(diào)優(yōu)各參數(shù)解析便是在此步驟完成的。

(三)執(zhí)行main方法

線程棧大小確定后,通過ContinueInNewThread方法創(chuàng)建新線程,并執(zhí)行JavaMain函數(shù),大概流程如下:

1、新建JVM實例

InitializeJVM方法調(diào)用InvocationFunctions的CreateJavaVM方法,即調(diào)用JVM.dll函數(shù)JNI_CreateJavaVM,新建一個JVM實例,該過程比較復(fù)雜。

2、加載入口類

通常在命令行中運行如下命令即指明入口類路徑

# 直接指名入口類路徑
java HelloWorld.class
# 通過包類配置入口類路徑
java -jar HelloWorld.jar

3、查找main方法

通過GetStaticMethodID方法查找指定main方法名的靜態(tài)方法。

4、執(zhí)行main方法

通過JavaCalls::call回調(diào)執(zhí)行main方法。需要注意的是,這里執(zhí)行main方法不是Java語言的方法,是經(jīng)過虛擬機解釋(或者編譯)后,操作系統(tǒng)能夠理解的二進制可執(zhí)行方法。

三、解析字節(jié)碼

(一)解釋字節(jié)碼

1、基于棧指令集

iconst_1    將 1 放入棧頂
iconst_1    將 1 放入棧頂
iadd        將棧頂?shù)?2 個數(shù)相加后結(jié)果放入棧頂
istore_0    將相加的結(jié)果放入局部變量表

基于棧的指令集優(yōu)點是虛擬機解釋器是可跨平臺移植的,換句話說不同平臺的虛擬機解釋器代碼可以復(fù)用。

2、基于寄存器指令集

mov eax,1 把 EAX 寄存器的值設(shè)為 1
add eax,1 再把這個值加 1 ,結(jié)果保存在了 EAX 寄存器

基于寄存器指令集的優(yōu)點是執(zhí)行速度相對于棧較快,原因是出棧入棧本身就涉及了大量的指令,而且棧是在內(nèi)存中實現(xiàn)的,更底層的匯編指令性能更高。

基于寄存器指令集的缺點是虛擬機解釋器是不可跨平臺移植,需要針對不同平臺的虛擬機做不同實現(xiàn)??紤]到不同平臺已經(jīng)使用不同的虛擬機程序,因此此過程多用戶透明。

虛擬機通過解釋器來翻譯字節(jié)碼文件中的指令比較順其自然,可是對于服務(wù)器端高頻執(zhí)行的程序來說,中間的翻譯過程相對耗時。解釋字節(jié)碼的方式適用于對啟動性能要求高,并且執(zhí)行頻率較低的應(yīng)用程序。

(二)編譯字節(jié)碼

最初,JVM 中的字節(jié)碼是由解釋器( Interpreter )完成編譯的,當虛擬機發(fā)現(xiàn)某個方法或代碼塊的運行特別頻繁的時候,就會把這些代碼認定為熱點代碼。

為了提高熱點代碼的執(zhí)行效率,在運行時,即時編譯器(JIT,Just In Time)會把這些代碼編譯成與本地平臺相關(guān)的機器碼,并進行各層次的優(yōu)化,然后保存到內(nèi)存中。

在 HotSpot 虛擬機中,內(nèi)置了兩種 JIT,分別為C1 編譯器C2 編譯器,這兩個編譯器的編譯過程是不一樣的。

1、C1 編譯器

C1 編譯器是一個簡單快速的編譯器,主要的關(guān)注點在于局部性的優(yōu)化,適用于執(zhí)行時間較短或?qū)有阅苡幸蟮某绦?,也稱為Client Compiler,例如,GUI 應(yīng)用對界面啟動速度就有一定要求。

2、C2 編譯器

C2 編譯器是為長期運行的服務(wù)器端應(yīng)用程序做性能調(diào)優(yōu)的編譯器,適用于執(zhí)行時間較長或?qū)Ψ逯敌阅苡幸蟮某绦?,也稱為Server Compiler,例如,服務(wù)器上長期運行的 Java 應(yīng)用對穩(wěn)定運行就有一定的要求。

3、分層編譯

分層編譯將 JVM 的執(zhí)行狀態(tài)分為了 5 個層次:

第 0 層:程序解釋執(zhí)行,默認開啟性能監(jiān)控功能(Profiling),如果不開啟,可觸發(fā)第二層編譯;
第 1 層:可稱為 C1 編譯,將字節(jié)碼編譯為本地代碼,進行簡單、可靠的優(yōu)化,不開啟 Profiling;
第 2 層:也稱為 C1 編譯,開啟 Profiling,僅執(zhí)行帶方法調(diào)用次數(shù)和循環(huán)回邊執(zhí)行次數(shù) profiling 的 C1 編譯;
第 3 層:也稱為 C1 編譯,執(zhí)行所有帶 Profiling 的 C1 編譯;
第 4 層:可稱為 C2 編譯,也是將字節(jié)碼編譯為本地代碼,但是會啟用一些編譯耗時較長的優(yōu)化,甚至?xí)鶕?jù)性能監(jiān)控信息進行一些不可靠的激進優(yōu)化。

通常情況下,C2 的執(zhí)行效率比 C1 高出30%以上。

在 Java8 中,默認開啟分層編譯。如果只想開啟 C2,可以關(guān)閉分層編譯(-XX:-TieredCompilation),如果只想用 C1,可以在打開分層編譯的同時,使用參數(shù):-XX:TieredStopAtLevel=1

通過 java -version命令行可以查看到當前虛擬機解析字節(jié)碼的方式,mixed mode表示既有解釋模式也有即是編譯模式。

java version "1.8.0_261"
Java(TM) SE Runtime Environment (build 1.8.0_261-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, mixed mode)

mixed mode代表是默認的混合編譯模式,除了這種模式外,我們還可以使用-Xint參數(shù)強制虛擬機運行于只有解釋器的編譯模式下;也可以使用參數(shù)-Xcomp強制虛擬機運行于只有 JIT 的編譯模式下。

僅使用解釋模式

通過命令java -Xint -version設(shè)置僅使用解釋模式,interpreted mode表示解釋模式。

java version "1.8.0_261"
Java(TM) SE Runtime Environment (build 1.8.0_261-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, interpreted mode)

僅使用編譯模式

通過命令java -Xcomp -version設(shè)置僅使用編譯模式,compiled mode表示編譯模式。在編譯模式下,程序啟動能感覺到明顯的卡頓。

java version "1.8.0_261"
Java(TM) SE Runtime Environment (build 1.8.0_261-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, compiled mode)

四、小結(jié)

通過對Java虛擬機啟動過程的解析,特別是即時編譯環(huán)節(jié)的理解,Java應(yīng)用運行并不慢。當應(yīng)用中熱點代碼普遍被編譯成匯編指令(二進制可執(zhí)行命令)存放于內(nèi)存中時,可近似達到C語言原生程序的運行速度。

隨著算力與內(nèi)存成本日漸降低,通過空間復(fù)雜度置換時間復(fù)雜度的策略顯然是合理的,使用Java語言編寫需求萬千變化的應(yīng)用是第一選擇:既有跨平臺、內(nèi)存安全、框架生態(tài)豐富的優(yōu)點,也在運行效率方面積極改善,這種折中選擇與市場反饋保持一致。

到此這篇關(guān)于Java虛擬機啟動過程解析的文章就介紹到這了,更多相關(guān)Java虛擬機啟動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java編寫緩存工具類的示例代碼

    Java編寫緩存工具類的示例代碼

    這篇文章主要為大家詳細介紹了如何基于Java編寫一個緩存工具類,文中的示例代碼講解詳細,具有一定的參考價值,感興趣的小伙伴可以了解一下
    2023-07-07
  • 一文教你學(xué)會如何使用MyBatisPlus

    一文教你學(xué)會如何使用MyBatisPlus

    本篇文章,我們通過 MyBatis Plus 來對一張表進行 CRUD 操作,來看看是如何簡化我們開發(fā)的,文中通過代碼示例介紹的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-05-05
  • spring-boot使用Admin監(jiān)控應(yīng)用的方法

    spring-boot使用Admin監(jiān)控應(yīng)用的方法

    本篇文章主要介紹了spring-boot使用Admin監(jiān)控應(yīng)用的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • MyBatis圖文并茂講解注解開發(fā)多對多查詢

    MyBatis圖文并茂講解注解開發(fā)多對多查詢

    這篇文章主要介紹了SpringBoot中Mybatis注解多對多查詢的實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • IDEA maven依賴錯誤中包下面紅色波浪線

    IDEA maven依賴錯誤中包下面紅色波浪線

    這篇文章主要介紹了IDEA maven依賴錯誤中包下面紅色波浪線,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 獲取Spring當前配置的兩種方式

    獲取Spring當前配置的兩種方式

    這篇文章主要給大家介紹了獲取Spring當前配置的,兩種方式文中通過代碼示例給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-01-01
  • SpringBoot實現(xiàn)自定義Starter的步驟詳解

    SpringBoot實現(xiàn)自定義Starter的步驟詳解

    在SpringBoot中,Starter是一種特殊的依賴,它可以幫助我們快速地集成一些常用的功能,例如數(shù)據(jù)庫連接、消息隊列、Web框架等。在本文中,我們將介紹如何使用Spring Boot實現(xiàn)自定義Starter,需要的朋友可以參考下
    2023-06-06
  • 一篇文章徹底搞懂面試中常被問的各種“鎖”

    一篇文章徹底搞懂面試中常被問的各種“鎖”

    這篇文章主要給大家介紹了關(guān)于面試中常被問的各種“鎖”的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • spring cloud openfeign 源碼實例解析

    spring cloud openfeign 源碼實例解析

    這篇文章主要介紹了spring cloud openfeign 源碼實例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • shiro攔截認證的全過程記錄

    shiro攔截認證的全過程記錄

    Apache?Shiro是一個強大且易用的Java安全框架,執(zhí)行身份驗證、授權(quán)、密碼和會話管理,下面這篇文章主要給大家介紹了關(guān)于shiro攔截認證的相關(guān)資料,需要的朋友可以參考下
    2021-11-11

最新評論

嘉禾县| 马关县| 涿州市| 宜兰市| 杭锦后旗| 响水县| 苏尼特右旗| 台东市| 房产| 山东省| 大港区| 东安县| 英吉沙县| 无锡市| 称多县| 渭南市| 拜泉县| 永安市| 麻栗坡县| 平潭县| 涪陵区| 太湖县| 九江县| 赤峰市| 焦作市| 密云县| 长沙市| 攀枝花市| 石林| 合水县| 巴彦淖尔市| 醴陵市| 定南县| 沁源县| 宣威市| 孟津县| 台江县| 漳平市| 漾濞| 登封市| 江西省|