- 好好學(xué)Java:從零基礎(chǔ)到項(xiàng)目實(shí)戰(zhàn)
- 歐陽(yáng)燊
- 1390字
- 2022-07-27 19:14:48
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)
- Designing Machine Learning Systems with Python
- Python數(shù)據(jù)可視化:基于Bokeh的可視化繪圖
- JavaScript語(yǔ)言精髓與編程實(shí)踐(第3版)
- Mastering Swift 2
- Monitoring Elasticsearch
- Backbone.js Blueprints
- Scientific Computing with Scala
- R大數(shù)據(jù)分析實(shí)用指南
- 小程序,巧應(yīng)用:微信小程序開(kāi)發(fā)實(shí)戰(zhàn)(第2版)
- Canvas Cookbook
- 零基礎(chǔ)學(xué)C語(yǔ)言第2版
- Spring Boot+MVC實(shí)戰(zhàn)指南
- 工業(yè)機(jī)器人離線編程
- Python Deep Learning
- Java程序設(shè)計(jì)入門(mén)(第2版)