初識(shí)Java虛擬機(jī)
1. 什么是Java虛擬機(jī)
虛擬機(jī)是一種抽象化的計(jì)算機(jī),通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的。Java虛擬機(jī)有自己完善的硬體架構(gòu),如處理器、堆棧、寄存器等,還具有相應(yīng)的指令系統(tǒng)。JVM屏蔽了與具體操作系統(tǒng)平臺(tái)相關(guān)的信息,使得Java程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。
Java虛擬機(jī)存在的原因是可以屏蔽底層操作系統(tǒng)的不同,使得同一個(gè)java文件編譯生成的字節(jié)碼文件可以通過(guò)不同的操作系統(tǒng)對(duì)應(yīng)的java虛擬機(jī),它把字節(jié)碼解釋成具體平臺(tái)上的機(jī)器指令執(zhí)行 。java使得java語(yǔ)言可以做到”一次編譯,到處運(yùn)行“。因此,java是一種跨平臺(tái)的語(yǔ)言。
因?yàn)橛辛薐ava虛擬機(jī)這一層“解釋”,會(huì)使得java程序運(yùn)行時(shí)間比C/C++等語(yǔ)言慢。
2. 從進(jìn)程的角度理解JVM
眾所周知,Java虛擬機(jī)是運(yùn)行在操作系統(tǒng)之中的,那么它在運(yùn)行的時(shí)候就是操作系統(tǒng)的一個(gè)進(jìn)程,因?yàn)檫M(jìn)程是操作系統(tǒng)的執(zhí)行單位。當(dāng)它在運(yùn)行的時(shí)候,它就是一個(gè)操作系統(tǒng)中的進(jìn)程實(shí)例,當(dāng)它沒(méi)有在運(yùn)行時(shí)(作為可執(zhí)行文件存放于文件系統(tǒng)中),可以把它叫做程序。
javac xxx.java
java xxx
相信上面兩條命令,大家肯定很熟悉了。執(zhí)行完第一步之后,生成java文件對(duì)應(yīng)的字節(jié)碼,而操作系統(tǒng)是無(wú)法直接識(shí)別字節(jié)碼的,此時(shí)就需要調(diào)用操作系統(tǒng)對(duì)應(yīng)的虛擬機(jī)將字節(jié)碼解釋成操作系統(tǒng)所能識(shí)別的二進(jìn)制可執(zhí)行文件。此時(shí)我們調(diào)用了一個(gè)名叫java的程序,而這個(gè)程序運(yùn)行之后就是一個(gè)JVM實(shí)例。
執(zhí)行的流程
java命令執(zhí)行后啟動(dòng)虛擬機(jī)進(jìn)程,虛擬機(jī)進(jìn)程啟動(dòng)完畢之后會(huì)讀取參數(shù)(即 java命令后面接的.class文件名和一些命令行傳參的參數(shù)),把他作為初始類(lèi)加載到內(nèi)存,對(duì)這個(gè)類(lèi)進(jìn)行初始化和動(dòng)態(tài)鏈接。(初始化和動(dòng)態(tài)鏈接在后面會(huì)講,此處留個(gè)印象即可)接下來(lái)便是從該類(lèi)的main方法開(kāi)始執(zhí)行。
總結(jié)分析
- .class文件不是直接被系統(tǒng)加載之后就直接在CPU執(zhí)行的,而是被一個(gè)叫做虛擬機(jī)的進(jìn)程托管的。首先必須虛擬機(jī)進(jìn)程啟動(dòng)就緒,然后由虛擬機(jī)中的類(lèi)加載器加載必要的class文件,包括jdk中的基礎(chǔ)類(lèi)(如String和Object等),然后由虛擬機(jī)進(jìn)程解釋class字節(jié)碼指令,把這些字節(jié)碼指令翻譯成本機(jī)cpu能夠識(shí)別的指令,才能在cpu上運(yùn)行。
- 更深層次的講,當(dāng)我們?cè)谶\(yùn)行class文件的時(shí)候,其實(shí)真正執(zhí)行的是Java虛擬機(jī)進(jìn)程,而不是我們的程序。那我們寫(xiě)的編譯生成的class文件是有什么作用呢?它只是虛擬機(jī)進(jìn)程執(zhí)行時(shí)需要的“原料”。這些“原料”在運(yùn)行時(shí)被加載到虛擬機(jī)中,被虛擬機(jī)解釋執(zhí)行,以控制虛擬機(jī)實(shí)現(xiàn)我們java代碼中所定義的一些相對(duì)高層的操作,比如創(chuàng)建一個(gè)文件等,**可以將class文件中的信息看做對(duì)虛擬機(jī)的控制信息,也就是一種虛擬指令。 **虛擬機(jī)只是處理一些底層的操作,例如內(nèi)存的分配和釋放等等。
3.JVM體系結(jié)構(gòu)簡(jiǎn)介
一個(gè)Java虛擬機(jī)在運(yùn)行過(guò)程中有三個(gè)子系統(tǒng)保證它的正常運(yùn)行,分別是類(lèi)加載器子系統(tǒng),執(zhí)行引擎子系統(tǒng),垃圾收集子系統(tǒng)。
類(lèi)加載器子系統(tǒng)
這個(gè)子系統(tǒng)用來(lái)在運(yùn)行的時(shí)候根據(jù)需要?jiǎng)討B(tài)加載類(lèi),“根據(jù)需要”代表的便是當(dāng)虛擬機(jī)運(yùn)行過(guò)程中需要該類(lèi),才會(huì)去加載它,而不是一次性加載所有的類(lèi)。
執(zhí)行引擎子系統(tǒng)
由虛擬機(jī)加載的類(lèi),被加載到Java虛擬機(jī)內(nèi)存中之后,虛擬機(jī)會(huì)讀取并執(zhí)行它里面存在的字節(jié)碼指令。虛擬機(jī)中執(zhí)行字節(jié)碼指令的部分叫做執(zhí)行引擎。
垃圾收集子系統(tǒng)
Java虛擬機(jī)會(huì)進(jìn)行自動(dòng)內(nèi)存管理。具體說(shuō)來(lái)就是自動(dòng)釋放沒(méi)有用的對(duì)象,而不需要程序員編寫(xiě)代碼來(lái)釋放分配的內(nèi)存。這部分工作由垃圾收集子系統(tǒng)負(fù)責(zé)。
歡迎關(guān)注本人博客:https://allen-yu.com/