乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      深入淺出:圖形化淺析JAVA程序運(yùn)行模式及虛擬機(jī)JVM

       諤諤熱 2017-09-03

      本文主要對(duì)Java程序的執(zhí)行模式和JVM的架構(gòu)原理進(jìn)行較易理解的介紹和剖析,以便能更好的掌握J(rèn)ava的核心機(jī)制和基本原理,拋磚引玉,以便引起Java愛(ài)好這的興趣。如果覺(jué)得有用,請(qǐng)點(diǎn)個(gè)贊,順手分享本文。Thanks a lot.

      一、Java程序的兩個(gè)環(huán)境

      所謂Java程序,即用Java語(yǔ)言編寫(xiě)的程序,它包含數(shù)據(jù)、代碼以及相關(guān)算法。而一個(gè)有效的java程序,滿(mǎn)足兩個(gè)環(huán)境的要求,即編譯環(huán)境和運(yùn)行環(huán)境。如下圖所示:

      深入淺出:圖形化淺析JAVA程序運(yùn)行模式及虛擬機(jī)JVM

      圖-1:Java程序運(yùn)行環(huán)

      根據(jù)上圖所示:

      其一,在編譯環(huán)境中,我們基于Java語(yǔ)言和JDK(Java開(kāi)發(fā)工具包),進(jìn)行源程序的代碼編寫(xiě),并在確保正確的情況下,通過(guò)工具包提供編譯器,把所有源代碼(即.java)編譯成(通過(guò)javac命令實(shí)現(xiàn))字節(jié)碼文件(即.class文件)。

      其二,在運(yùn)行時(shí)環(huán)境執(zhí)行程序,或說(shuō)運(yùn)行程序。這時(shí),需要先擁有待運(yùn)行程序的字節(jié)碼文件。這些字節(jié)碼文件有可能通過(guò)網(wǎng)絡(luò)或者在本地兩種方式傳遞到運(yùn)行時(shí)環(huán)境。

      運(yùn)行時(shí)環(huán)境中主要的工作就是啟動(dòng)Java虛擬機(jī),并通過(guò)虛擬機(jī)來(lái)完成一系列工作,實(shí)現(xiàn)java程序的運(yùn)行。需要注意的是,在java虛擬執(zhí)行程序時(shí),它會(huì)根據(jù)需要來(lái)加載Java提供的相關(guān)API的class文件。

      二、Java的JVM運(yùn)行結(jié)構(gòu)

      基于上面的java程序運(yùn)行的框架圖,我們進(jìn)一步來(lái)透視java的核心基石,即java虛擬機(jī)JVM的內(nèi)部運(yùn)行組成。

      根據(jù)Java的虛擬機(jī)規(guī)范,JVM內(nèi)部抽象體系結(jié)構(gòu)主要有這樣幾大部分組成,即類(lèi)裝載器子系統(tǒng)、執(zhí)行引擎以及運(yùn)行時(shí)數(shù)據(jù)管理區(qū),同時(shí)要求支持本地方法的調(diào)用機(jī)制。那么這樣一來(lái),我們進(jìn)一步細(xì)化Java程序的JVM內(nèi)部執(zhí)行機(jī)制,就形成如下的Java運(yùn)行模式架構(gòu):

      深入淺出:圖形化淺析JAVA程序運(yùn)行模式及虛擬機(jī)JVM

      圖-2:JVM運(yùn)行流程結(jié)構(gòu)圖

      三、JVM的架構(gòu)原理和運(yùn)行機(jī)制

      經(jīng)過(guò)上一部分的內(nèi)容的抽象和總結(jié),那么我們可以進(jìn)一步抽象出基于java虛擬機(jī)規(guī)范實(shí)現(xiàn)的一般的JVM實(shí)現(xiàn)組成架構(gòu)以及其運(yùn)行機(jī)制和原理。JVM詳細(xì)的參考架構(gòu)圖如下:

      深入淺出:圖形化淺析JAVA程序運(yùn)行模式及虛擬機(jī)JVM

      圖-3:虛擬機(jī)JVM參考實(shí)現(xiàn)圖

      針對(duì)上圖JVM參考架構(gòu),作簡(jiǎn)要說(shuō)明如下:

      虛擬機(jī)JVM主要有三個(gè)子系統(tǒng)構(gòu)成:

      1-類(lèi)裝入器子系統(tǒng)

      2-運(yùn)行時(shí)數(shù)據(jù)區(qū)

      3-執(zhí)行引擎

      1.類(lèi)裝入器子系統(tǒng)

      Java的動(dòng)態(tài)類(lèi)加載功能是由類(lèi)裝入器子系統(tǒng)。 由他進(jìn)行類(lèi)的裝載、鏈接、并初始化類(lèi)文件時(shí),是指一個(gè)類(lèi)第一次運(yùn)行時(shí),而不是編譯時(shí)間。

      1.1類(lèi)加載

      深入淺出:圖形化淺析JAVA程序運(yùn)行模式及虛擬機(jī)JVM

      1)Bootstrap類(lèi)加載器

      負(fù)責(zé)加載$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++實(shí)現(xiàn),不是ClassLoader子類(lèi)

      2)Extension類(lèi)加載器

      負(fù)責(zé)加載java平臺(tái)中擴(kuò)展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目錄下的jar包

      3)Application類(lèi)加載器

      負(fù)責(zé)記載classpath中指定的jar包及目錄中class

      4)Custom類(lèi)加載器

      屬于應(yīng)用程序根據(jù)自身需要自定義的ClassLoader,如tomcat、jboss都會(huì)根據(jù)j2ee規(guī)范自行實(shí)現(xiàn)ClassLoader。加載過(guò)程中會(huì)先檢查類(lèi)是否被已加載,檢查順序是自底向上,從Custom ClassLoader到BootStrap ClassLoader逐層檢查,只要某個(gè)classloader已加載就視為已加載此類(lèi),保證此類(lèi)只所有ClassLoader加載一次。而加載的順序是自頂向下,也就是由上層來(lái)逐層嘗試加載此類(lèi)。

      1.2連接

      驗(yàn)證——字節(jié)碼校驗(yàn)器會(huì)檢查生成的字節(jié)碼是否正確,如果驗(yàn)證失敗則會(huì)驗(yàn)證錯(cuò)誤。

      準(zhǔn)備——對(duì)于所有靜態(tài)變量的內(nèi)存分配和默認(rèn)值分配。

      識(shí)別——解析或識(shí)別是從運(yùn)行時(shí)常量池的符號(hào)引用中動(dòng)態(tài)具體值的過(guò)程。

      1.3初始化

      這是類(lèi)裝入的最后階段, 類(lèi)或接口的初始化由執(zhí)行類(lèi)或接口初始化方法構(gòu)成。這里所有的靜態(tài)變量與原來(lái)的值將被指派,靜態(tài)塊將被執(zhí)行。

      2.運(yùn)行時(shí)數(shù)據(jù)區(qū)

      運(yùn)行時(shí)數(shù)據(jù)區(qū)域分為5個(gè)主要組件:

      深入淺出:圖形化淺析JAVA程序運(yùn)行模式及虛擬機(jī)JVM

      方法區(qū)——所有的類(lèi)級(jí)別的數(shù)據(jù)將存儲(chǔ)在這里,包括靜態(tài)變量。 每個(gè)JVM區(qū)域只有一個(gè)方法,它是一個(gè)共享資源。一般會(huì)包含一個(gè)運(yùn)行時(shí)常量池(運(yùn)行時(shí)常量池:一個(gè)存儲(chǔ)了類(lèi)文件格式中的常量池表的內(nèi)存空間。這部分空間雖然存在于方法區(qū)內(nèi),但卻在JVM操作中扮演著舉足輕重的角色,因此JVM規(guī)范單獨(dú)把這一部分拿出來(lái)描述。除了每個(gè)類(lèi)或接口中定義的常量,它還包含了所有對(duì)方法和字段的引用。因此當(dāng)需要一個(gè)方法或字段時(shí),JVM通過(guò)運(yùn)行時(shí)常量池中的信息從內(nèi)存空間中來(lái)查找其相應(yīng)的實(shí)際地址)。

      堆區(qū)域——所有的對(duì)象和相應(yīng)的實(shí)例變量和數(shù)組將存儲(chǔ)在這里。 還有一堆區(qū)域每個(gè)JVM。 自方法和堆區(qū)域多個(gè)線程共享內(nèi)存,存儲(chǔ)的數(shù)據(jù)不是線程安全的。

      棧區(qū)域——每一個(gè)線程創(chuàng)建一個(gè)單獨(dú)的運(yùn)行時(shí)堆棧。 對(duì)于每一個(gè)方法調(diào)用,一個(gè)稱(chēng)為棧內(nèi)存棧幀被創(chuàng)建。 所有局部變量將被創(chuàng)建在棧內(nèi)存中。 棧區(qū)域是線程安全的,因?yàn)樗皇且粋€(gè)共享資源。 棧幀分三個(gè)實(shí)體:

      其一,局部變量數(shù)組——有多少相關(guān)的方法局部變量以及相應(yīng)的值將被存儲(chǔ)在這里。

      其二,操作數(shù)棧——如果任何中間操作要求執(zhí)行,操作數(shù)棧作為運(yùn)行時(shí)工作區(qū)執(zhí)行操作。

      其三,幀數(shù)據(jù)——所有的符號(hào)對(duì)應(yīng)的方法存儲(chǔ)在這里。 在任何的情況下異常catch塊信息將保存在幀數(shù)據(jù)。

      程序計(jì)數(shù)器——每個(gè)線程必須分開(kāi)程序計(jì)數(shù)器登記,當(dāng)前執(zhí)行的指令一旦執(zhí)行,程序計(jì)數(shù)器(程序計(jì)數(shù)登記器)更新下一個(gè)指令。

      本地方法棧——本地方法棧保存本機(jī)方法的信息。 為每一個(gè)線程將創(chuàng)建一個(gè)單獨(dú)的本地方法棧,以備不時(shí)之用。

      3.執(zhí)行引擎

      通過(guò)類(lèi)裝載器裝載的,被分配到JVM的運(yùn)行時(shí)數(shù)據(jù)區(qū)的字節(jié)碼會(huì)被執(zhí)行引擎執(zhí)行。執(zhí)行引擎以指令為單位讀取Java字節(jié)碼。它就像一個(gè)CPU一樣,一條一條地執(zhí)行機(jī)器指令。每個(gè)字節(jié)碼指令都由一個(gè)1字節(jié)的操作碼和附加的操作數(shù)組成。執(zhí)行引擎取得一個(gè)操作碼,然后根據(jù)操作數(shù)來(lái)執(zhí)行任務(wù),完成后就繼續(xù)執(zhí)行下一條操作碼。如下圖所示:

      深入淺出:圖形化淺析JAVA程序運(yùn)行模式及虛擬機(jī)JVM

      不過(guò)Java字節(jié)碼是用一種人類(lèi)可以讀懂的語(yǔ)言編寫(xiě)的,而不是用機(jī)器可以直接執(zhí)行的語(yǔ)言。因此,執(zhí)行引擎必須把字節(jié)碼轉(zhuǎn)換成可以直接被JVM執(zhí)行的語(yǔ)言。字節(jié)碼可以通過(guò)以下兩種方式轉(zhuǎn)換成合適的語(yǔ)言。執(zhí)行引擎主要包括3部分內(nèi)容:

      (1)解釋器:一條一條地讀取,解釋并且執(zhí)行字節(jié)碼指令。因?yàn)樗粭l一條地解釋和執(zhí)行指令,所以它可以很快地解釋字節(jié)碼,但是執(zhí)行起來(lái)會(huì)比較慢。這是解釋執(zhí)行的語(yǔ)言的一個(gè)缺點(diǎn)。字節(jié)碼這種“語(yǔ)言”基本來(lái)說(shuō)是解釋執(zhí)行的。

      (2)即時(shí)(Just-In-Time)編譯器:即時(shí)編譯器被引入用來(lái)彌補(bǔ)解釋器的缺點(diǎn)。執(zhí)行引擎首先按照解釋執(zhí)行的方式來(lái)執(zhí)行,然后在合適的時(shí)候,即時(shí)編譯器把整段字節(jié)碼編譯成本地代碼。然后,執(zhí)行引擎就沒(méi)有必要再去解釋執(zhí)行方法了,它可以直接通過(guò)本地代碼去執(zhí)行它。執(zhí)行本地代碼比一條一條進(jìn)行解釋執(zhí)行的速度快很多。編譯后的代碼可以執(zhí)行的很快,因?yàn)楸镜卮a是保存在緩存里的。

      不過(guò),用JIT編譯器來(lái)編譯代碼所花的時(shí)間要比用解釋器去一條條解釋執(zhí)行花的時(shí)間要多。因此,如果代碼只被執(zhí)行一次的話,那么最好還是解釋執(zhí)行而不是編譯后再執(zhí)行。因此,內(nèi)置了JIT編譯器的JVM都會(huì)檢查方法的執(zhí)行頻率,如果一個(gè)方法的執(zhí)行頻率超過(guò)一個(gè)特定的值的話,那么這個(gè)方法就會(huì)被編譯成本地代碼。JIT中不要構(gòu)成如下:

      2中間代碼生成器(Intermediate Code Generator):生成中間代碼

      2代碼優(yōu)化器(Code Optimizer):負(fù)責(zé)優(yōu)化上面生成的中間代碼

      2目標(biāo)代碼生成器(Target Code Generator):負(fù)責(zé)生成機(jī)器代碼或本地代碼

      2分析器(Profiler):一個(gè)特殊組件,負(fù)責(zé)查找熱點(diǎn),即該方法是否被多次調(diào)用;

      可以簡(jiǎn)單這樣理解,JIT編譯器通過(guò)中間代碼生成器生成中間代碼,再通過(guò)代碼優(yōu)化器負(fù)責(zé)優(yōu)化生成中間代碼,最后由目標(biāo)代碼生成器負(fù)責(zé)生成機(jī)器代碼或本機(jī)代碼。在這過(guò)程中,JIT的分析器,一個(gè)特殊的組件,負(fù)責(zé)尋找熱點(diǎn),即是否多次調(diào)用的方法,再執(zhí)行上述操作。

      (3)垃圾收集器(Garbage Collector):收集和刪除未引用的對(duì)象??梢酝ㄟ^(guò)調(diào)用System.gc()觸發(fā)垃圾收集,但不能保證執(zhí)行。JVM的垃圾回收對(duì)象是已創(chuàng)建的對(duì)象。

      另外,Java Native Interface(JNI): JNI將與本機(jī)方法庫(kù)進(jìn)行交互,并提供執(zhí)行引擎所需的本機(jī)庫(kù)。本地方法庫(kù)(Native Method Libraries)是執(zhí)行引擎所需的本機(jī)庫(kù)的集合。

      (文末)——謝謝閱讀,希望對(duì)你有所幫助。別忘了,點(diǎn)個(gè)贊、分享本文,并關(guān)注本頭條號(hào)喲~


        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多