中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Java虛擬機(jī)(JVM)概述

2018-07-28    來源:importnew

容器云強(qiáng)勢上線!快速搭建集群,上萬Linux鏡像隨意使用

JVM(Java虛擬機(jī))是一個抽象的計算模型。就如同一臺真實(shí)的機(jī)器,它有自己的指令集和執(zhí)行引擎,可以在運(yùn)行時操控內(nèi)存區(qū)域。目的是為構(gòu)建在其上運(yùn)行的應(yīng)用程序提供一個運(yùn)行環(huán)境。JVM可以解讀指令代碼并與底層進(jìn)行交互:包括操作系統(tǒng)平臺和執(zhí)行指令并管理資源的硬件體系結(jié)構(gòu)。本文主要對JVM進(jìn)行概述,并介紹Java程序是如何在上面執(zhí)行的。

虛擬機(jī)

從本質(zhì)上講,虛擬機(jī)是個被構(gòu)建來提供特定或通用目的服務(wù)環(huán)境的非實(shí)體計算機(jī)。這聽起來像是一個仿真器,用來仿真機(jī)器未配置或不能按要求執(zhí)行任務(wù)的硬件組件。因此,我們要做的就是創(chuàng)建一個軟件,以軟件的形式模擬硬件提供的服務(wù),使之看起來這個特定的硬件在系統(tǒng)中是實(shí)際存在的。虛擬機(jī)在一定程度上使用CPU虛擬化,為實(shí)際的硬件問題提供一個接口。所以可以說它實(shí)際上有兩種功能:提供一個虛擬的環(huán)境,或者將某些不存在的事物進(jìn)行抽象化。但是當(dāng)我們深入了解之后會發(fā)現(xiàn),這兩種功能有著很明顯的不同。我們現(xiàn)在暫且不看它們之間的不同點(diǎn),它們的共同點(diǎn)在于都“假裝”成它們不是的東西。正如Popek和Goldberg在論文“Formal Requirements for Virtualizable Third Generation Architectures”里說的,它是“一個真實(shí)機(jī)器有效、獨(dú)立的復(fù)制品!

基于不同的需求和用途,虛擬機(jī)有很多類型。一種叫完全虛擬化(full virtualization),這種虛擬機(jī)表現(xiàn)得像一臺真正的機(jī)器。其他類型的虛擬機(jī)會更精細(xì),更專業(yè),比如進(jìn)程虛擬化(process virtualization)。而對JVM進(jìn)行分類是很困難的,因?yàn)樗鼘PU進(jìn)行了虛擬化,有自己的運(yùn)行時環(huán)境、與底層平臺協(xié)調(diào)工作的內(nèi)存管理器、垃圾收集器,當(dāng)然還有大量作為中間字節(jié)碼輸入的類庫,最后但同樣重要的是,它能夠模擬機(jī)器的寄存器、堆棧等等。簡單地說,它是被Java編譯器編譯為java的本質(zhì)——字節(jié)碼的游樂場。字節(jié)碼實(shí)際上是JVM用來將代碼重新翻譯為本地機(jī)器指令所使用的機(jī)器代碼。

類文件格式

有趣的是,其實(shí)JVM并不關(guān)心Java語言或其他編程語言的語義和語法結(jié)構(gòu)。當(dāng)JVM執(zhí)行一段程序的時候,它主要關(guān)注的是一種稱為“類文件”的特定文件格式。*.class類文件格式和Java代碼定義的面向?qū)ο蟮念惤Y(jié)構(gòu)毫無關(guān)系。編譯器將*.java文件編譯成*.class文件,然后JVM對*.class文件進(jìn)行解譯,它不關(guān)心這個類文件是由哪種編譯器生成的,只要符合類文件的文件格式即可。Java編譯器將一段程序編譯為等價的類文件。這些類文件實(shí)際上包含了半編譯的代碼——字節(jié)碼。之所以稱之為半編譯,是因?yàn)樽止?jié)碼并不像C/C++編譯器編譯的二進(jìn)制文件一樣會被直接執(zhí)行。字節(jié)碼要先被輸入到JVM中,然后再轉(zhuǎn)換為底層平臺可以執(zhí)行的最終指令。所以字節(jié)碼包含了JVM的指令、符號表和其他的輔助信息。不管何種語言,能根據(jù)JVM的語法和結(jié)構(gòu)約束編譯生成字節(jié)碼的編譯器,都是一個可以在JVM上執(zhí)行的候選者。

JVM的定位

JVM將自身定位于字節(jié)碼和底層平臺之間。底層平臺是指操作系統(tǒng)(OS)和硬件。操作系統(tǒng)和硬件體系結(jié)構(gòu)在不同的機(jī)器上可能不同,但是同一段Java程序可以不用做任何的代碼修改就能在不同的機(jī)器上運(yùn)行。這是在虛擬環(huán)境中執(zhí)行的程序語言的獨(dú)特之處。例如,由其他程序語言編譯器編譯的目標(biāo)代碼如C++和Java相比的不同點(diǎn)在于,C++程序需要被特定平臺的編譯器重新編譯,從而使它能在不同的體系結(jié)構(gòu)上面運(yùn)行。而Java代碼并不需要做任何改變,因?yàn)橛蒍ava編譯器編譯的字節(jié)碼是在外圍的JVM上執(zhí)行。因此,JVM負(fù)責(zé)重新解譯由Java編譯器生成的字節(jié)碼,并和底層平臺協(xié)調(diào)工作。也就是說,盡管Java編譯器生成的結(jié)果是平臺獨(dú)立的,但JVM與特定平臺相關(guān)的。除非兩臺機(jī)器有相同的體系結(jié)構(gòu),在某個體系結(jié)構(gòu)上安裝和使用的JVM可能換一臺機(jī)器就不能正常工作了。

圖1 JVM結(jié)構(gòu)

相對于JVM, JRE和JDK又是什么?

想要運(yùn)行Java程序,我們需要JVM因?yàn)樗峁┝俗止?jié)碼的運(yùn)行環(huán)境。Oracle提供了兩種不同的產(chǎn)品:JDK(Java開發(fā)工具)和JRE(Java運(yùn)行環(huán)境)。JRE是我們安裝運(yùn)行Java程序的最基本軟件。它和Java類庫以及運(yùn)行Java程序所需要的其他組件一起夠成了JVM的一個實(shí)現(xiàn)。所以,如果我們想運(yùn)行一個類文件或一段字節(jié)碼,僅需要JRE就夠了。而JDK(Java開發(fā)工具)是JRE的超集。它包含了JRE提供的所有東西,包括創(chuàng)建類文件的工具如Java編譯器、調(diào)試器和其他許多開發(fā)Java程序相關(guān)的工具。所以,當(dāng)我們要創(chuàng)建類文件(編譯Java源碼)時,我們就需要JDK。下面是一張Java API文檔的截圖。注意組成JDK,JRE和Java SE API核心類庫的組件;通過這張截圖你可以了解JRE和JDK里面都有哪些內(nèi)容。

Java提供了Java虛擬機(jī)規(guī)范來讓我們對JVM的工作原理有一個完整的認(rèn)識。你可以從這里得到概念性知識,并開發(fā)一個自己的JVM;但這并不是一個簡單的工作。現(xiàn)在市場上已經(jīng)有很多JVM了,其中有些是免費(fèi)的,還有一些需要購買商業(yè)許可證才能使用。

在JVM上執(zhí)行Java程序

每一個在JRE上運(yùn)行的Java程序都會創(chuàng)建一個JVM實(shí)例。編譯后的Java類文件和其他被依賴的類文件會被加載到運(yùn)行環(huán)境中。這一步由類加載器協(xié)助完成。

類加載器通過三步完成類加載。

Firstly, it loads the program classes, along with standard Java classes that are bundled with JDK in the form of bytecode. The standard classes form the core API library of Java. The bootstrap begins by locating the core API libraries classes typically situated in?jre/lib.

首先,類加載器會以字節(jié)碼的形式加載程序類文件和與JDK綁定的標(biāo)準(zhǔn)Java類文件。標(biāo)準(zhǔn)類文件構(gòu)成了Java API核心類庫。引導(dǎo)程序通過定位通常位于jre/lib目錄下的核心API類庫啟動。

然后,擴(kuò)展機(jī)制定位擴(kuò)展類庫,例如一些為開發(fā)或執(zhí)行代碼而被添加到Java里新的(可選)包。擴(kuò)展類通常位于?jre/lib/ext目錄下。有時,擴(kuò)展類會被放到系統(tǒng)屬性java.ext.dirs?定義的其他目錄下面。程序包使用JAR或ZIP的擴(kuò)展名。

最后,如果要加載的類沒有在Java的標(biāo)準(zhǔn)類庫或擴(kuò)展類庫中被找到,加載器會搜索CLASSPATH環(huán)境變量下定義的文件路徑,CLASSPATH里面包含了諸多存儲類文件的地址。系統(tǒng)屬性java.class.path對CLASSPATH環(huán)境變量做了映射。

像JAR或ZIP這樣的歸檔文件都是包含了一些其他文件目錄的獨(dú)立文件,通常是壓縮文件格式。例如,程序中使用的標(biāo)準(zhǔn)類庫包含在歸檔文件?rt.jar中,該文件會和JDK被一同安裝。

一旦文件被定位并加載之后,類加載器會執(zhí)行不同的功能,例如根據(jù)JVM的約束進(jìn)行校驗(yàn)、內(nèi)存分配,或者在調(diào)用構(gòu)造器設(shè)置定義的變量元素之前使用默認(rèn)值初始化類變量。

當(dāng)加載程序結(jié)束之后,字節(jié)碼指令被傳遞給執(zhí)行引擎。然后JVM借助于綁定到指定平臺的特定JVM實(shí)現(xiàn)的本地代碼和底層操作系統(tǒng)進(jìn)行交互。請注意,不同平臺的實(shí)現(xiàn)可能有略微不同。

數(shù)據(jù)存儲區(qū)的堆空間用于存儲動態(tài)或臨時分配的內(nèi)存空間。類和數(shù)組是在這塊區(qū)域里創(chuàng)建的。當(dāng)創(chuàng)建對象大小超出堆內(nèi)存空間時,垃圾收集器會回收內(nèi)存。

Java棧,又叫棧幀,用于存儲局部變量和不同階段方法調(diào)用的臨時結(jié)果。每一次方法調(diào)用都會創(chuàng)建一個棧幀。

方法區(qū)基本上是JVM線程間的共享存儲區(qū)。

寄存器是一個模擬的底層機(jī)器寄存器,主要用于執(zhí)行字節(jié)碼指令。PC寄存器或程序計數(shù)器是用于保存當(dāng)前指令執(zhí)行地址的主要寄存器。

JVM功能概述

JVM的功能可以歸納為:

  • 加載:通過類加載器加載類文件的過程。
  • 鏈接:鏈接類文件,提交給JVM在運(yùn)行時執(zhí)行。
  • 初始化:分配內(nèi)存和調(diào)用類初始化方法設(shè)置變量值。

總結(jié)

使用虛擬機(jī)執(zhí)行程序的最大好處是它是平臺獨(dú)立的。和C/C++這種高效的語言相比,這種類型編程語言的生產(chǎn)力可以彌補(bǔ)其性能上的弱點(diǎn)。本文僅僅是對JVM的一點(diǎn)淺見,但也許已經(jīng)足以幫助理解JVM是如何實(shí)際工作的。

原文鏈接: developer 翻譯: ImportNew.com - 辰午
譯文鏈接: http://www.importnew.com/29224.html
[ 轉(zhuǎn)載請保留原文出處、譯者和譯文鏈接。]

關(guān)于作者: 辰午

查看辰午的更多文章 >>

標(biāo)簽: 代碼 搜索

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:OpenJDK 里的 AsmTools 簡介

下一篇:KodExplorer 4.32 傳輸速度優(yōu)化,開放二次開發(fā) API