核心基礎(chǔ):理解何為JVM?掌握J(rèn)ava虛擬機(jī)構(gòu)成精髓
Java虛擬機(jī)是一個(gè)程序,其目的是執(zhí)行其他程序。 這是一個(gè)簡要的觀念,也是我們編碼功夫***的示例之一。 JVM打破了當(dāng)時(shí)的現(xiàn)狀,并繼續(xù)支持今天的編程創(chuàng)新。
1.JVM的用法和定義
JVM有兩個(gè)主要功能:允許Java程序在任何設(shè)備或操作系統(tǒng)上運(yùn)行(稱為"一次寫入,隨處運(yùn)行",即"Write once, run anywhere"原則),以及管理和優(yōu)化程序內(nèi)存。 當(dāng)Java于1995年發(fā)布時(shí),所有計(jì)算機(jī)程序都被寫入特定的操作系統(tǒng),程序n內(nèi)存由軟件開發(fā)人員管理。 所以說,JVM是一個(gè)新模式啟示。
圖-1:JVM高層視圖
擁有JVM的技術(shù)定義是很有用的,那樣,軟件開發(fā)人員就可以通過常規(guī)的方式思考它。這可以分解表述如下:
- 技術(shù)定義:JVM是執(zhí)行代碼并為該代碼提供運(yùn)行時(shí)環(huán)境的軟件程序的規(guī)范。
- 常規(guī)定義:JVM是我們運(yùn)行Java程序的工作方式。 我們配置JVM的設(shè)置,然后依賴它來在執(zhí)行期間管理程序資源。
當(dāng)開發(fā)人員談?wù)揓VM時(shí),我們通常是指在一臺(tái)機(jī)器上運(yùn)行的進(jìn)程,尤其是服務(wù)器,它代表并控制Java應(yīng)用程序的資源使用情況。這些是參照J(rèn)VM規(guī)范實(shí)現(xiàn)的的——所謂JVM規(guī)范,其描述了構(gòu)建執(zhí)行這些任務(wù)的程序的要求。
那么,誰開發(fā)和維護(hù)JVM?
——JVM由一些非常聰明的程序員、公司和開源組織來廣泛部署、大量使用、升級(jí)開發(fā)和維護(hù)的。 OpenJDK項(xiàng)目是Sun Microsystems決定開源Java的后代。Sun被Oracle收購,OpenJDK繼續(xù)通過Oracle來對(duì)Java管理,現(xiàn)在由Oracle工程師完成了大量繁重工作。
2.JVM中內(nèi)存管理
與正在運(yùn)行的JVM最常見的交互是檢查堆(Heap)和堆棧(stack,簡稱為棧)中的內(nèi)存使用情況。 最常見的調(diào)整是調(diào)優(yōu)JVM的內(nèi)存設(shè)置。
2.1.垃圾回收
在Java之前,所有程序內(nèi)存都由程序員管理。 在Java中,程序內(nèi)存由JVM管理。 JVM通過稱為垃圾收集的進(jìn)程來管理內(nèi)存,該進(jìn)程持續(xù)識(shí)別并消除Java程序中未使用的內(nèi)存。 垃圾收集發(fā)生在正在運(yùn)行的JVM中。
在早期,Java因?yàn)闆]有像C那樣"接近源質(zhì)(close the metal)"而受到很多批評(píng),因此沒有那么快。 垃圾收集過程尤其引起爭議。 從那時(shí)起,已經(jīng)提出了各種算法和方法,并用于垃圾收集。 隨著兼容性開發(fā)和優(yōu)化,垃圾收集得到了極大的改進(jìn)。
注:接近源質(zhì)是什么意思?
——當(dāng)程序員說編程語言或平臺(tái)"接近源質(zhì)"時(shí),我們的意思是開發(fā)人員能夠以編程方式(通過編寫代碼)管理操作系統(tǒng)的內(nèi)存。 從理論上講,程序員可以通過規(guī)定使用多少以及何時(shí)丟棄它,以便從我們的程序中獲得更多性能。 在大多數(shù)情況下,將內(nèi)存管理委派給高度精煉的流程(如JVM)可以產(chǎn)生超過你自己管理的更好性能和更少錯(cuò)誤。
3. JVM分為三部分
3.1.JVM規(guī)范
首先,JVM是一個(gè)軟件規(guī)范。 以某種通告或宣告方式表達(dá)其要求,JVM規(guī)范強(qiáng)調(diào)其實(shí)現(xiàn)細(xì)節(jié)不在其規(guī)范中具體定義,以便在其實(shí)現(xiàn)中實(shí)現(xiàn)***的創(chuàng)造性(如下通告要求):
"要正確實(shí)現(xiàn)Java虛擬機(jī),您只需要能夠讀取類文件格式并正確執(zhí)行其中指定的操作。"
還有這樣的例子,如J.S. 巴赫(Bach)曾經(jīng)類似的描述過音樂創(chuàng)作:
"你所要做的就是在合適的時(shí)間觸碰那正確的調(diào)調(diào)(就是音樂家或唱歌所說那個(gè)key,鍵)。"
因此,JVM所要做的就是正確運(yùn)行Java程序。 聽起來很簡單,甚至可能從外面看起來也很簡單,但這是一項(xiàng)艱巨的任務(wù),特別是考慮到Java語言的強(qiáng)大功能和靈活性。
注意,JVM就是個(gè)虛擬的機(jī)器,可進(jìn)一步描述如下:
JVM是一個(gè)以便攜方式運(yùn)行Java類(class)文件的虛擬機(jī)器機(jī)。 作為虛擬機(jī),意味著JVM是底層實(shí)際機(jī)器的抽象——例如運(yùn)行程序的服務(wù)器。 無論實(shí)際存在哪種操作系統(tǒng)或硬件,JVM都會(huì)為程序在其中運(yùn)行創(chuàng)建可預(yù)測的環(huán)境。 但是,與真正的虛擬機(jī)不同,JVM不會(huì)創(chuàng)建虛擬操作系統(tǒng)。 將JVM描述為托管運(yùn)行時(shí)環(huán)境或進(jìn)程虛擬機(jī)會(huì)更準(zhǔn)確。
3.2.JVM實(shí)現(xiàn)
實(shí)現(xiàn)JVM規(guī)范會(huì)產(chǎn)生一個(gè)實(shí)際的軟件程序,這是一個(gè)JVM實(shí)現(xiàn)。 事實(shí)上,有許多JVM實(shí)現(xiàn),包括開源和專有。 OpenJDK的HotSpot JVM是參考實(shí)現(xiàn),并且仍然是世界上經(jīng)過最徹底試驗(yàn)和測試(tried-and-tested)的代碼庫之一。 HotSpot也是最常用的JVM。
幾乎所有許可的JVM都是作為OpenJDK和HotSpot JVM的分支而創(chuàng)建的,包括Oracle的許可JDK。 從OpenJDK創(chuàng)建許可分支的開發(fā)人員通常希望添加特定于操作系統(tǒng)的性能改進(jìn)。 通常,您將JVM作為Java Runtime Environment(JRE)的捆綁部分下載和安裝。
3.3.JVM實(shí)例
在JVM規(guī)范被實(shí)現(xiàn)并作為軟件產(chǎn)品發(fā)布后,您可以下載并作為程序運(yùn)行它。下載的程序是JVM的實(shí)例(或?qū)嵗姹?。
大多數(shù)時(shí)候,當(dāng)開發(fā)人員談?wù)?quot;JVM"時(shí),我們指的是在軟件開發(fā)或生產(chǎn)環(huán)境中運(yùn)行的JVM實(shí)例。 您可能會(huì)說,"嘿,Solo,這個(gè)服務(wù)器上的JVM使用了多少內(nèi)存?" 或者,"我無法相信我創(chuàng)建了一個(gè)循環(huán)調(diào)用,并且堆棧溢出錯(cuò)誤導(dǎo)致我的JVM崩潰。這是一個(gè)新手錯(cuò)誤啊!"
提示:軟件規(guī)范是何物?
軟件規(guī)范(或規(guī)范)是描述軟件系統(tǒng)應(yīng)如何操作的人類可讀設(shè)計(jì)文檔。規(guī)范的目的是為工程師編碼創(chuàng)建一份清晰的描述和要求。
4.JVM加載和執(zhí)行class文件
我們已經(jīng)討論了JVM在運(yùn)行Java應(yīng)用程序中的作用,但它如何執(zhí)行其功能? 為了運(yùn)行Java應(yīng)用程序,JVM依賴于Java類加載器和Java執(zhí)行引擎。
4.1.Java類加載器
Java中的所有東西都是類(或者每件東西都是一個(gè)類),所有Java應(yīng)用程序都是從類構(gòu)建的。 應(yīng)用程序可以包含一個(gè)類或數(shù)千個(gè)。 為了運(yùn)行Java應(yīng)用程序,JVM必須將已編譯的.class文件加載到可以訪問它們的上下文(例如服務(wù)器)中。 JVM依賴于其類加載器來執(zhí)行此功能。
Java類加載器是JVM的一部分,它將類加載到內(nèi)存中并使它們可用于執(zhí)行。 類加載器使用延遲加載和緩存等技術(shù)來使類加載盡可能高效。 也就是說,類加載不是(比如說)便攜式運(yùn)行時(shí)內(nèi)存管理的史詩般的腦筋急轉(zhuǎn)彎,也就是說這些技術(shù)相對(duì)簡單。
每個(gè)Java虛擬機(jī)都包含一個(gè)類加載器。 JVM規(guī)范描述了在運(yùn)行時(shí)查詢和操作類加載器的標(biāo)準(zhǔn)方法,但JVM實(shí)現(xiàn)負(fù)責(zé)實(shí)現(xiàn)這些功能。 從開發(fā)人員的角度來看,底層的類加載器機(jī)制通常是一個(gè)黑盒子。注意,一般具體的JVM實(shí)現(xiàn),也不止一個(gè)類加載器。
4.2.Java執(zhí)行引擎
一旦類加載器完成了加載類的工作,JVM就開始在每個(gè)類中執(zhí)行代碼。 執(zhí)行引擎是處理此功能的JVM組件。 執(zhí)行引擎對(duì)于運(yùn)行JVM至關(guān)重要。 實(shí)際上,出于所有實(shí)際目的,它就是JVM實(shí)例。
執(zhí)行代碼涉及管理對(duì)系統(tǒng)資源的訪問。JVM執(zhí)行引擎位于正在運(yùn)行的程序(包括對(duì)文件、網(wǎng)絡(luò)和內(nèi)存資源的需求)和提供這些資源的操作系統(tǒng)之間。
4.3.執(zhí)行引擎如何管理系統(tǒng)資源
系統(tǒng)資源可以分為兩大類:內(nèi)存和其他所有內(nèi)容。
回想一下,JVM負(fù)責(zé)處理未使用的內(nèi)存,垃圾收集是執(zhí)行這種處理的機(jī)制。 JVM還負(fù)責(zé)分配和維護(hù)開發(fā)人員認(rèn)為理所當(dāng)然的參照性結(jié)構(gòu)。 舉個(gè)例子,JVM的執(zhí)行引擎負(fù)責(zé)在Java中使用類似new關(guān)鍵字的東西,并將其轉(zhuǎn)換為特定于操作系統(tǒng)的內(nèi)存分配請(qǐng)求。
除了內(nèi)存管理,執(zhí)行引擎還管理文件系統(tǒng)訪問和網(wǎng)絡(luò)I/O的資源。 由于JVM可跨操作系統(tǒng)進(jìn)行互操作,因此這絕非易事。 除了每個(gè)應(yīng)用程序的資源需求外,執(zhí)行引擎還必須響應(yīng)每個(gè)OS環(huán)境。這就是JVM能夠處理內(nèi)部需求的方式。
5. JVM演變:過去,現(xiàn)在,未來
1995年,JVM引入了兩個(gè)革命性的概念,這些概念從此成為現(xiàn)代軟件開發(fā)的標(biāo)準(zhǔn)配置:"一次編寫,隨處運(yùn)行"和自動(dòng)內(nèi)存管理。 軟件互操作性在當(dāng)時(shí)是一個(gè)大膽的概念,但今天很少有開發(fā)人員會(huì)三思而后行。 同樣,雖然我們的工程先驅(qū)必須自己管理程序內(nèi)存,但我這一代人是在垃圾收集器(garbage collection)中長大。
我們可以說James Gosling和Brendan Eich發(fā)明了現(xiàn)代編程,但在接下來的幾十年里,成千上萬的其他人已經(jīng)完善并內(nèi)置了他們的想法(編程方式的內(nèi)部性的觀念認(rèn)知)。 雖然Java虛擬機(jī)最初只是用于Java,但現(xiàn)在它已經(jīng)發(fā)展到支持許多腳本和編程語言,包括Scala,Groovy和Kotlin。 展望未來,很難看到未來JVM不是發(fā)展領(lǐng)域的重要組成部分(依然是突出的組成部分)。
6.結(jié)論
本文總覽性對(duì)JVM進(jìn)行了介紹,具體設(shè)計(jì)的內(nèi)容還很多,這里就不一一展開了,可以看本號(hào)已發(fā)表的相關(guān)文章,以進(jìn)一步了解。***,我以一張JVM組成圖來總結(jié)本文,以更直觀的方式認(rèn)識(shí)和感知Java 虛擬機(jī)( Java virtual machine):
Java 虛擬機(jī)實(shí)現(xiàn)架構(gòu)參考
本篇關(guān)于認(rèn)知JVM精要組成的內(nèi)容,就到這里了。具體的JVM不是小小的一篇網(wǎng)文就能全部搞定的。