欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

講一講JVM的組成(Java經(jīng)典面試題)

  發(fā)布時(shí)間:2019-04-10 15:33:08   作者:王磊的博客   我要評(píng)論
JVM(Java 虛擬機(jī))算是面試必問(wèn)的問(wèn)題的了,而但凡問(wèn) JVM 一定會(huì)問(wèn)的第一個(gè)問(wèn)題就是:講一講 JVM 的組成?那本文就注重講一下 JVM 的組成,感興趣的可以了解一下

JVM(Java 虛擬機(jī))算是面試必問(wèn)的問(wèn)題的了,而但凡問(wèn) JVM 一定會(huì)問(wèn)的第一個(gè)問(wèn)題就是:講一講 JVM 的組成?那本文就注重講一下 JVM 的組成。

首先來(lái)說(shuō) JVM 的組成分為,整體組成部分和運(yùn)行時(shí)數(shù)據(jù)區(qū)組成部分,一般開(kāi)發(fā)者關(guān)注的和面試官問(wèn)的都是后者,但本文會(huì)詳細(xì)講解以上兩個(gè)組成部分。

我們先把JVM這個(gè)虛擬機(jī)畫(huà)出來(lái),如下圖所示:
virtual虛擬機(jī)
Machine 機(jī)械
java Virtual Machine (java 虛擬機(jī))

從這個(gè)圖中可以看到,JVM是運(yùn)行在操作系統(tǒng)之上的,它與硬件沒(méi)有直接的交互。我們?cè)賮?lái)看下JVM有哪些組成部分,如下圖所示:

一、JVM 整體組成

JVM 整體組成可分為以下四個(gè)部分:

  • 類加載器(ClassLoader)
  • 運(yùn)行時(shí)數(shù)據(jù)區(qū)(Runtime Data Area)
  • 執(zhí)行引擎(Execution Engine)
  • 本地庫(kù)接口(Native Interface)

各個(gè)組成部分的用途:

程序在執(zhí)行之前先要把java代碼轉(zhuǎn)換成字節(jié)碼(class文件),jvm首先需要把字節(jié)碼通過(guò)一定的方式 類加載器(ClassLoader) 把文件加載到內(nèi)存中 運(yùn)行時(shí)數(shù)據(jù)區(qū)(Runtime Data Area) ,而字節(jié)碼文件是jvm的一套指令集規(guī)范,并不能直接交個(gè)底層操作系統(tǒng)去執(zhí)行,因此需要特定的命令解析器 執(zhí)行引擎(Execution Engine) 將字節(jié)碼翻譯成底層系統(tǒng)指令再交由CPU去執(zhí)行,而這個(gè)過(guò)程中需要調(diào)用其他語(yǔ)言的接口 本地庫(kù)接口(Native Interface) 來(lái)實(shí)現(xiàn)整個(gè)程序的功能,這就是這4個(gè)主要組成部分的職責(zé)與功能。

而我們通常所說(shuō)的jvm組成指的是運(yùn)行時(shí)數(shù)據(jù)區(qū)(Runtime Data Area),因?yàn)橥ǔP枰绦騿T調(diào)試分析的區(qū)域就是“運(yùn)行時(shí)數(shù)據(jù)區(qū)”,或者更具體的來(lái)說(shuō)就是“運(yùn)行時(shí)數(shù)據(jù)區(qū)”里面的Heap(堆)模塊,那接下來(lái)我們來(lái)看運(yùn)行時(shí)數(shù)據(jù)區(qū)(Runtime Data Area)是由哪些模塊組成的。

二、運(yùn)行時(shí)數(shù)據(jù)區(qū)組成

jvm的運(yùn)行時(shí)數(shù)據(jù)區(qū),不同虛擬機(jī)實(shí)現(xiàn)可能略微有所不同,但都會(huì)遵從Java虛擬機(jī)規(guī)范,Java 8 虛擬機(jī)規(guī)范規(guī)定,Java虛擬機(jī)所管理的內(nèi)存將會(huì)包括以下幾個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)域:

程序計(jì)數(shù)器(Program Counter Register)

Java虛擬機(jī)棧(Java Virtual Machine Stacks)

本地方法棧(Native Method Stack)

Java堆(Java Heap)

方法區(qū)(Methed Area)

接下來(lái)我們分別介紹每個(gè)區(qū)域的用途。

①、Java程序計(jì)數(shù)器

程序計(jì)數(shù)器(Program Counter Register)是一塊較小的內(nèi)存空間,它可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。在虛擬機(jī)的概念模型里,字節(jié)碼解析器的工作是通過(guò)改變這個(gè)計(jì)數(shù)器的值來(lái)選取下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個(gè)計(jì)數(shù)器來(lái)完成。

特性:內(nèi)存私有

由于jvm的多線程是通過(guò)線程輪流切換并分配處理器執(zhí)行時(shí)間的方式來(lái)實(shí)現(xiàn)的,也就是任何時(shí)刻,一個(gè)處理器(或者說(shuō)一個(gè)內(nèi)核)都只會(huì)執(zhí)行一條線程中的指令。因此為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每個(gè)線程都有獨(dú)立的程序計(jì)數(shù)器。

異常規(guī)定:無(wú)

如果線程正在執(zhí)行Java中的方法,程序計(jì)數(shù)器記錄的就是正在執(zhí)行虛擬機(jī)字節(jié)碼指令的地址,如果是Native方法,這個(gè)計(jì)數(shù)器就為空(undefined),因此該內(nèi)存區(qū)域是唯一一個(gè)在Java虛擬機(jī)規(guī)范中沒(méi)有規(guī)定OutOfMemoryError的區(qū)域。

②、Java虛擬機(jī)棧

Java虛擬機(jī)棧(Java Virtual Machine Stacks)描述的是Java方法執(zhí)行的內(nèi)存模型,每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)線幀(Stack Frame)用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息,每個(gè)方法從調(diào)用直至執(zhí)行完成的過(guò)程,都對(duì)應(yīng)著一個(gè)線幀在虛擬機(jī)棧中入棧到出棧的過(guò)程。

特性:內(nèi)存私有,它的生命周期和線程相同。

異常規(guī)定:StackOverflowError、OutOfMemoryError

1、如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的棧深度就會(huì)拋出StackOverflowError異常。

2、如果虛擬機(jī)是可以動(dòng)態(tài)擴(kuò)展的,如果擴(kuò)展時(shí)無(wú)法申請(qǐng)到足夠的內(nèi)存就會(huì)拋出OutOfMemoryError異常。

③、本地方法棧

本地方法棧(Native Method Stack)與虛擬機(jī)棧的作用是一樣的,只不過(guò)虛擬機(jī)棧是服務(wù)Java方法的,而本地方法棧是為虛擬機(jī)調(diào)用Native方法服務(wù)的。

在Java虛擬機(jī)規(guī)范中對(duì)于本地方法棧沒(méi)有特殊的要求,虛擬機(jī)可以自由的實(shí)現(xiàn)它,因此在Sun HotSpot虛擬機(jī)直接把本地方法棧和虛擬機(jī)棧合二為一了。

特性和異常:同虛擬機(jī)棧,請(qǐng)參考上面知識(shí)點(diǎn)。

④、Java堆

Java堆(Java Heap)是Java虛擬機(jī)中內(nèi)存最大的一塊,是被所有線程共享的,在虛擬機(jī)啟動(dòng)時(shí)候創(chuàng)建,Java堆唯一的目的就是存放對(duì)象實(shí)例,幾乎所有的對(duì)象實(shí)例都在這里分配內(nèi)存,隨著JIT編譯器的發(fā)展和逃逸分析技術(shù)的逐漸成熟,棧上分配、標(biāo)量替換優(yōu)化的技術(shù)將會(huì)導(dǎo)致一些微妙的變化,所有的對(duì)象都分配在堆上漸漸變得不那么“絕對(duì)”了。

特性:內(nèi)存共享

異常規(guī)定:OutOfMemoryError

如果在堆中沒(méi)有內(nèi)存完成實(shí)例分配,并且堆不可以再擴(kuò)展時(shí),將會(huì)拋出OutOfMemoryError。

Java虛擬機(jī)規(guī)范規(guī)定,Java堆可以處在物理上不連續(xù)的內(nèi)存空間中,只要邏輯上連續(xù)即可,就像我們的磁盤(pán)空間一樣。在實(shí)現(xiàn)上也可以是固定大小的,也可以是可擴(kuò)展的,不過(guò)當(dāng)前主流的虛擬機(jī)都是可擴(kuò)展的,通過(guò)-Xmx和-Xms控制。

⑤、方法區(qū)

方法區(qū)(Methed Area)用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯后的代碼等數(shù)據(jù)。

誤區(qū):方法區(qū)不等于永生代

很多人原因把方法區(qū)稱作“永久代”(Permanent Generation),本質(zhì)上兩者并不等價(jià),只是HotSpot虛擬機(jī)垃圾回收器團(tuán)隊(duì)把GC分代收集擴(kuò)展到了方法區(qū),或者說(shuō)是用來(lái)永久代來(lái)實(shí)現(xiàn)方法區(qū)而已,這樣能省去專門為方法區(qū)編寫(xiě)內(nèi)存管理的代碼,但是在Jdk8也移除了“永久代”,使用Native Memory來(lái)實(shí)現(xiàn)方法區(qū)。

特性:內(nèi)存共享

異常規(guī)定:OutOfMemoryError

當(dāng)方法無(wú)法滿足內(nèi)存分配需求時(shí)會(huì)拋出OutOfMemoryError異常。

三、擴(kuò)展知識(shí)

本節(jié)將擴(kuò)展一些和內(nèi)存分配有關(guān)的知識(shí)。

運(yùn)行時(shí)常量池

運(yùn)行時(shí)常量池是方法區(qū)的一部分,Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項(xiàng)信息是常量池(Constant Pool Table)用于存放編譯期生成的各種字面量和符號(hào)引用,這部分在類加載后進(jìn)入方法區(qū)的運(yùn)行是常量池中,如String類的intern()方法。

直接內(nèi)存

直接內(nèi)存(Direct Memory)并不是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分,但這部分內(nèi)存也會(huì)被頻繁的使用,而且可能導(dǎo)致OutOfMemoryError。在JDK 1.4中新加入了NIO類,引入了一種基于Channel與緩沖區(qū)Buffer的IO方式,它通過(guò)一個(gè)存儲(chǔ)在Java堆中的DirectByteBuffer對(duì)象作為這塊內(nèi)存的引用操作,它因此更高效,它避免了Java堆和Native堆來(lái)回交換數(shù)據(jù)的時(shí)間。

注意:直接內(nèi)存分配不會(huì)受到Java堆大小的限制,但是受到本機(jī)總內(nèi)存大小限制,在設(shè)置虛擬機(jī)參數(shù)的時(shí)候,不能忽略直接內(nèi)存,把實(shí)際內(nèi)存設(shè)置為-Xmx,使得內(nèi)存區(qū)域的總和大于物理內(nèi)存的限制,從而導(dǎo)致動(dòng)態(tài)擴(kuò)展時(shí)出現(xiàn)OutOfMemoryError異常。

四、總結(jié)

本文講了jvm的主要組成部分,以及組成部分中最重要的運(yùn)行時(shí)數(shù)據(jù)區(qū)(Runtime Data Area)的構(gòu)成,其中程序計(jì)數(shù)器、虛擬機(jī)棧和本地方法為私有內(nèi)存,會(huì)隨著線程而生,隨著線程而滅,而Java堆作為最大的內(nèi)存區(qū)域?qū)⑹情_(kāi)發(fā)人員重點(diǎn)關(guān)注的內(nèi)存區(qū)域,還有方法區(qū)以及運(yùn)行時(shí)常量區(qū)與永生代的關(guān)系,最后講了直接內(nèi)存的實(shí)現(xiàn)過(guò)程已經(jīng)使用時(shí)需要主要的點(diǎn),希望能夠幫助大家更好的理解jvm。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 10道JVM常見(jiàn)面試題解析(附答案)

    這篇文章主要介紹了10道JVM常見(jiàn)面試題解析(附答案),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)
    2020-09-04
  • JVM相關(guān)面試題及答案(小結(jié))

    這篇文章主要介紹了JVM相關(guān)面試題及答案(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-02
  • 2020面試阿里字節(jié)跳動(dòng)90%被問(wèn)到的JVM面試題附答案(史上最全)

    這篇文章主要介紹了2020面試阿里字節(jié)跳動(dòng)90%被問(wèn)到的JVM面試題附答案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-15
  • 2020年JVM高頻率面試題整理

    這篇文章主要介紹了2020年JVM高頻率面試題整理,真是小編下了血本給大家整理出來(lái)的,值得大家收藏,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-09
  • JVM面試題小結(jié)(2020最新版)

    這篇文章主要介紹了JVM面試題小結(jié)(2020最新版),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-21
  • 2019年JVM面試都問(wèn)了什么?(附答案解析)

    這篇文章主要介紹了2019年JVM面試都問(wèn)了什么?(附答案解析),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-04
  • Java研發(fā)面試99題(含答案):JVM+Spring+MySQL+線程池+鎖

    這篇文章主要介紹了Java研發(fā)面試99題,主要包括了JVM,Spring,MySQL,線程池,鎖等,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-16
  • 30道有趣的JVM面試題(小結(jié))

    這篇文章主要介紹了30道有趣的JVM面試題(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-26

最新評(píng)論