官术网_书友最值得收藏!

1.3.2 JVM的體系結(jié)構(gòu)

Java虛擬機(jī)這個(gè)名稱聽(tīng)起來(lái)很高端,其實(shí)它不過(guò)是一套程序包而已,這些程序構(gòu)成了系統(tǒng)平臺(tái)里面的Java運(yùn)行環(huán)境。在Java編程領(lǐng)域,人們更習(xí)慣將Java虛擬機(jī)稱作JVM,免得產(chǎn)生誤解。

JVM主要分為5大模塊,包括類加載器、運(yùn)行時(shí)數(shù)據(jù)區(qū)、執(zhí)行引擎、本地方法接口和垃圾收集模塊,簡(jiǎn)要說(shuō)明如下:

1.類加載器

顧名思義,類加載器用于加載Java的類文件(class文件),也就是把一個(gè)或若干個(gè)class文件讀到內(nèi)存中,并為其指定唯一標(biāo)識(shí),以便外部訪問(wèn)class文件內(nèi)部的數(shù)據(jù)與接口。

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

數(shù)據(jù)區(qū)存放著Java程序在運(yùn)行時(shí)需要的各種數(shù)據(jù)空間,包含棧區(qū)、堆區(qū)、PC寄存器、本地方法棧、方法區(qū)5類數(shù)據(jù),分別說(shuō)明如下。

  • 棧區(qū):存放當(dāng)前正在執(zhí)行的方法所需的各項(xiàng)數(shù)據(jù),包括基本類型變量、對(duì)象的引用、方法的返回地址等。每個(gè)線程都擁有自己的棧區(qū),且棧內(nèi)數(shù)據(jù)不可被其他線程訪問(wèn)。
  • 堆區(qū):存放程序用到的所有對(duì)象信息,堆區(qū)里的數(shù)據(jù)可被程序的所有線程共享。
  • PC寄存器(程序計(jì)數(shù)寄存器):注意此PC指的是Program Counter(程序計(jì)數(shù)器),而非Personal Computer(個(gè)人計(jì)算機(jī))。JVM支持多線程運(yùn)行,每個(gè)線程都擁有自己的PC寄存器,寄存器中保存著當(dāng)前正在執(zhí)行的指令地址。
  • 本地方法棧:這是一個(gè)特殊的棧區(qū),用于同本地方法接口之間的數(shù)據(jù)交互。
  • 方法區(qū):主要存放已經(jīng)被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯后的代碼等  數(shù)據(jù)。

其中,棧區(qū)、堆區(qū)、方法區(qū)存放的數(shù)據(jù)是有關(guān)聯(lián)的。每段Java代碼定義了各自的類,這些類信息就保存在方法區(qū);一個(gè)類可以創(chuàng)建多個(gè)對(duì)象,這些對(duì)象信息就保存在堆區(qū);每個(gè)對(duì)象又會(huì)被多次用到,每次使用的時(shí)候,該對(duì)象的引用就保存在棧區(qū)。但不同版本的JDK對(duì)字符串常量的處理方式并不一樣,在JDK 1.7之前,字符串常量保存在方法區(qū),而在JDK 1.7之后,字符串常量改為保存到堆區(qū)了。

3.執(zhí)行引擎

因?yàn)镴VM采用自己的一套指令系統(tǒng),所以JVM通過(guò)執(zhí)行引擎來(lái)運(yùn)行字節(jié)碼。不同JVM采用的執(zhí)行技術(shù)不盡相同,常見(jiàn)的主要有3種,分別是解釋、即時(shí)編譯和自適應(yīng)優(yōu)化,簡(jiǎn)要介紹如下。

  • 解釋:第一代JVM采用解釋執(zhí)行,它將字節(jié)碼解釋為本地系統(tǒng)所能理解的機(jī)器碼。由于在運(yùn)行時(shí)才一條一條解釋成機(jī)器碼,因此該方式的執(zhí)行效率較低。
  • 即時(shí)編譯:即時(shí)編譯(Just-In-Time Compilation,JIT)屬于第二代JVM。當(dāng)JVM發(fā)現(xiàn)某個(gè)代碼塊會(huì)特別頻繁的運(yùn)行時(shí),就把該代碼塊全部編譯成機(jī)器碼,再執(zhí)行編譯好的這段機(jī)器碼。通過(guò)將多次解釋減少到一次編譯,從而提高程序的運(yùn)行效率。
  • 自適應(yīng)優(yōu)化:該方式在即時(shí)編譯的基礎(chǔ)上繼續(xù)改進(jìn),首次運(yùn)行時(shí)對(duì)所有代碼都采取解釋執(zhí)行,接著監(jiān)視代碼的執(zhí)行情況,對(duì)那些經(jīng)常調(diào)用的方法啟動(dòng)一個(gè)后臺(tái)線程,將其編譯為機(jī)器碼并加以優(yōu)化。如果某個(gè)方法不再頻繁使用,就取消它對(duì)應(yīng)的編譯代碼,恢復(fù)對(duì)其解釋執(zhí)行。

4.本地方法接口

本地方法接口(Java Native Interface,JNI)允許JVM上的程序調(diào)用本地程序和類庫(kù),或者被對(duì)方調(diào)用。這些本地程序和類庫(kù)由其他語(yǔ)言編寫(xiě),例如C語(yǔ)言、C++語(yǔ)言或匯編語(yǔ)言。通過(guò)JNI的協(xié)助,JVM能夠讓Java程序調(diào)用已經(jīng)存在的本地支持庫(kù),而無(wú)須關(guān)心底層的實(shí)現(xiàn)過(guò)程,這類本地服務(wù)包括但不限于:文件的輸入輸出、圖像的加工處理、音視頻的錄制與播放等。

5.垃圾收集模塊

因?yàn)槿魏卧O(shè)備的內(nèi)存都是有限的,所以JVM提供了垃圾收集機(jī)制,也就是回收那些已經(jīng)不用的對(duì)象,把它們占用的內(nèi)存空間釋放出來(lái)重新利用。譬如租房子,等到原來(lái)的房客離去之后,管家就要重新收拾這個(gè)房子,打掃干凈再去招徠新的房客。

總結(jié)一下,JVM各模塊的體系結(jié)構(gòu)及其相互關(guān)系如圖1-38所示。

圖1-38 JVM各模塊的體系結(jié)構(gòu)

主站蜘蛛池模板: 上饶市| 普格县| 镇宁| 博白县| 内江市| 沙湾县| 富阳市| 武功县| 华宁县| 彭水| 南宫市| 修武县| 巴青县| 简阳市| 宜昌市| 繁峙县| 任丘市| 玉屏| 石城县| 富锦市| 沧源| 河北省| 修文县| 天津市| 天镇县| 白玉县| 锡林郭勒盟| 阜平县| 栾川县| 鄂托克前旗| 钦州市| 寿阳县| 武义县| 美姑县| 玉树县| 沁水县| 乐平市| 西宁市| 容城县| 循化| 汉阴县|