溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

95%的技術(shù)面試必考的JVM知識(shí)點(diǎn)都在這,另附加分思路!

發(fā)布時(shí)間:2020-09-16 15:03:25 來(lái)源:網(wǎng)絡(luò) 閱讀:551 作者:Java_老男孩 欄目:編程語(yǔ)言

概述:知識(shí)點(diǎn)匯總

jvm的知識(shí)點(diǎn)匯總共6個(gè)大方向:內(nèi)存模型、類(lèi)加載機(jī)制、GC垃圾回收是比較重點(diǎn)的內(nèi)容。性能調(diào)優(yōu)部分偏重實(shí)際應(yīng)用,重點(diǎn)突出實(shí)踐能力。編譯器優(yōu)化和執(zhí)行模式部分偏重理論基礎(chǔ),主要掌握知識(shí)點(diǎn)。

各個(gè)部分的內(nèi)容如下:

1>內(nèi)存模型部分:程序計(jì)數(shù)器、方法區(qū)、堆、棧、本地方法棧的作用,保存哪些數(shù)據(jù);

2>類(lèi)加載部分:雙親委派的加載機(jī)制以及常用類(lèi)加載器分別加載哪種類(lèi)型的類(lèi);

3>GC部分分代回收的思想和依據(jù),以及不同垃圾回收算法實(shí)現(xiàn)的思路、適合的場(chǎng)景;

4>性能調(diào)優(yōu)部分:常用的jvm優(yōu)化參數(shù)的作用,參數(shù)調(diào)優(yōu)的依據(jù),要了解常用的jvm分析工具能分析哪類(lèi)問(wèn)題,以及使用方法;

5>執(zhí)行模式部分:解釋、編譯、混合模式的優(yōu)缺點(diǎn),了解java7提供的分層編譯技術(shù)。需要知道JIT即時(shí)編譯技術(shù)和OSR也就是棧上替換,知道C1、C2編譯器針對(duì)的場(chǎng)景,其中C2針對(duì)server模式,優(yōu)化更激進(jìn)。在新技術(shù)方面可以了解一下java10提供的由java實(shí)現(xiàn)的graal編譯器。

6>編譯優(yōu)化部分:前端編譯器javac的編譯過(guò)程、AST抽象語(yǔ)法樹(shù)、編譯期優(yōu)化和運(yùn)行期優(yōu)化。編譯優(yōu)化的常用技術(shù),包括公共子表達(dá)式的消除、方法內(nèi)聯(lián)、逃逸分析、棧上分配、同步消除等。明白了這些才能寫(xiě)出對(duì)編譯器友好的代碼。

jvm的內(nèi)容相對(duì)來(lái)說(shuō)比較集中,但是對(duì)知識(shí)深度的掌握要求較高,建議面試前重點(diǎn)加強(qiáng)。

一、jvm內(nèi)存相關(guān)考點(diǎn)

1.詳解-jvm內(nèi)存模型?

jvm內(nèi)存模型主要指運(yùn)行時(shí)的數(shù)據(jù)區(qū),包括5個(gè)部分。

棧也叫方法棧,是線(xiàn)程私有的,線(xiàn)程在執(zhí)行每個(gè)方法時(shí)都會(huì)同時(shí)創(chuàng)建一個(gè)棧幀,用來(lái)存儲(chǔ)局部變量表、操作棧、動(dòng)態(tài)鏈接、方法出口等信息。調(diào)用方法時(shí)執(zhí)行入棧,方法返回時(shí)執(zhí)行出棧。

本地方法棧與棧類(lèi)似,也是用來(lái)保存線(xiàn)程執(zhí)行方法時(shí)的信息,不同的是,執(zhí)行java方法使用棧,而執(zhí)行native方法使用本地方法棧。

程序計(jì)數(shù)器保存著當(dāng)前線(xiàn)程所執(zhí)行的字節(jié)碼位置,每個(gè)線(xiàn)程工作時(shí)都有一個(gè)獨(dú)立的計(jì)數(shù)器。程序計(jì)數(shù)器為執(zhí)行java方法服務(wù),執(zhí)行native方法時(shí),程序計(jì)數(shù)器為空。

棧、本地方法棧、程序計(jì)數(shù)器這三個(gè)部分都是線(xiàn)程獨(dú)占的。

堆是jvm管理的內(nèi)存中最大的一塊,堆被所有線(xiàn)程共享,目的是為了存放對(duì)象實(shí)例,幾乎所有的對(duì)象實(shí)例都在這里分配。當(dāng)堆內(nèi)存沒(méi)有可用的空間時(shí),會(huì)拋出OOM異常。根據(jù)對(duì)象存活的周期不同,jvm把堆內(nèi)存進(jìn)行分代管理,由垃圾回收器來(lái)進(jìn)行對(duì)象的回收管理。

方法區(qū)也是各個(gè)線(xiàn)程共享的內(nèi)存區(qū)域,又叫非堆區(qū)。用于存儲(chǔ)已被虛擬機(jī)加載的類(lèi)信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù),

jdk1.7中的永久代和1.8中的metaspace都是方法區(qū)的一種實(shí)現(xiàn)。

面試回答此知識(shí)點(diǎn)相關(guān)問(wèn)題時(shí),要答出兩個(gè)要點(diǎn):一個(gè)是各部分的功能,另一個(gè)是哪些線(xiàn)程共享,哪些獨(dú)占。

2.詳解-jmm內(nèi)存可見(jiàn)性? ? ?

jmm是java內(nèi)存模型,與剛才講到的jvm內(nèi)存模型是兩回事,jmm的主要目標(biāo)是定義程序中變量的訪(fǎng)問(wèn)規(guī)則,如圖所示,所有的共享變量都存儲(chǔ)在主內(nèi)存中共享。每個(gè)線(xiàn)程有自己的工作內(nèi)存,工作內(nèi)存中保存的是主內(nèi)存中變量的副本,線(xiàn)程對(duì)變量的讀寫(xiě)等操作必須在自己 的工作內(nèi)存中進(jìn)行,而不能直接讀寫(xiě)主內(nèi)存中的變量。

在多線(xiàn)程進(jìn)行數(shù)據(jù)交互時(shí),例如線(xiàn)程a給一個(gè)共享變量賦值后,由線(xiàn)程b來(lái)讀取這個(gè)值,a修改完變量是修改在自己的工作區(qū)內(nèi)存中,b是不可見(jiàn)的,只有從a的工作區(qū)寫(xiě)回到主內(nèi)存,b再?gòu)闹鲀?nèi)存讀取到自己的工作區(qū)才能進(jìn)行進(jìn)一步的操作。由于指令重排序的存在,這個(gè)寫(xiě)-讀的順序有可能被打亂。

因此jmm需要提供原子性、可見(jiàn)性、有序性的保證。

3、詳解-jmm保證

主要介紹下jmm如何保證原子性、可見(jiàn)性,有序性。

jmm保證對(duì)除long和double外的基礎(chǔ)數(shù)據(jù)類(lèi)型的讀寫(xiě)操作是原子性的。另外關(guān)鍵字Synchronized也可以提供原子性保證。Synchronized的原子性是通過(guò)java的兩個(gè)高級(jí)的字節(jié)碼指令monitorenter和monitorexit來(lái)保證的。

jmm可見(jiàn)性的保證,一個(gè)是通過(guò)Synchronized,另外一個(gè)就是volatile。volatile強(qiáng)制變量的賦值會(huì)同步刷新回主內(nèi)存,強(qiáng)制變量的讀取會(huì)從主內(nèi)存重新加載,保證不同的線(xiàn)程總是能夠看到該變量的最新值。

jmm對(duì)有序性的保證,主要通過(guò)volatile和一系列happens-before原則。volatile的另一個(gè)作用就是阻止指令重排序,這樣就可以保證變量讀寫(xiě)的有序性。

happens-before原則包括一系列規(guī)則,如

  • 程序順序原則,即一個(gè)線(xiàn)程內(nèi)必須保證語(yǔ)義串行性;

  • 鎖規(guī)則,即對(duì)同一個(gè)鎖的解鎖一定發(fā)生在再次加鎖之前;

  • 此外還包括happens-before原則的傳遞性、線(xiàn)程啟動(dòng)、中斷、終止規(guī)則等。

二、類(lèi)加載機(jī)制相關(guān)考點(diǎn)

1.詳解類(lèi)加載機(jī)制? ? ?

類(lèi)的加載指的是將編譯好的class類(lèi)文件中的字節(jié)碼讀入到內(nèi)存中,將其放在方法區(qū)內(nèi)并創(chuàng)建對(duì)應(yīng)的Class對(duì)象。

類(lèi)的加載分為加載、鏈接、初始化,其中鏈接又包括驗(yàn)證、準(zhǔn)備、解析三步??吹綀D中上半部分深綠色,我們逐個(gè)分析:

  • 加載是文件到內(nèi)存的過(guò)程。通過(guò)類(lèi)的完全限定名查找此類(lèi)字節(jié)碼文件,并利用字節(jié)碼文件創(chuàng)建一個(gè)Class對(duì)象

  • 驗(yàn)證是對(duì)類(lèi)文件內(nèi)容驗(yàn)證。目的在于確保Class文件符合當(dāng)前虛擬機(jī)要求,不會(huì)危害虛擬機(jī)自身安全。主要包括四種:文件格式驗(yàn)證,元數(shù)據(jù)驗(yàn)證,字節(jié)碼驗(yàn)證,符號(hào)引用驗(yàn)證。

  • 準(zhǔn)備階段是進(jìn)行內(nèi)存分配。為類(lèi)變量也就是類(lèi)中由static修飾的變量分配內(nèi)存,并且設(shè)置初始值,這里要注意,初始值是0或者null,而不是代碼中設(shè)置的具體值,代碼中設(shè)置的值是在初始化階段完成的。另外這里也不包含用final修飾的靜態(tài)變量,因?yàn)閒inal在編譯的時(shí)候就會(huì)分配了。

  • 解析主要是解析字段、接口、方法。主要是將常量池中的符號(hào)引用替換為直接引用的過(guò)程。直接引用就是直接指向目標(biāo)的指針、相對(duì)偏移量等。

  • 最后是初始化:主要完成靜態(tài)塊執(zhí)行與靜態(tài)變量的賦值。這是類(lèi)加載最后階段,若被加載類(lèi)的父類(lèi)沒(méi)有初始化,則先對(duì)父類(lèi)進(jìn)行初始化。

只有對(duì)類(lèi)主動(dòng)使用時(shí),才會(huì)進(jìn)行初始化,初始化的觸發(fā)條件包括創(chuàng)建類(lèi)的實(shí)例的時(shí)候、訪(fǎng)問(wèn)類(lèi)的靜態(tài)方法或者靜態(tài)變量的時(shí)候、Class.forName()反射類(lèi)的時(shí)候、或者某個(gè)子類(lèi)被初始化的時(shí)候。

類(lèi)的生命周期,就是從類(lèi)的加載到類(lèi)實(shí)例的創(chuàng)建與使用,再到類(lèi)對(duì)象不再被使用時(shí)可以被GC卸載回收。這里要注意一點(diǎn),由java虛擬機(jī)自帶的三種類(lèi)加載器加載的類(lèi)在虛擬機(jī)的整個(gè)生命周期中是不會(huì)被卸載的,只有用戶(hù)自定義的類(lèi)加載器所加載的類(lèi)才可以被卸載。

2.詳解類(lèi)加載器? ??

java自帶的三種類(lèi)加載器分別是:bootstrap啟動(dòng)類(lèi)加載器、擴(kuò)展類(lèi)加載器和應(yīng)用加載器也叫系統(tǒng)加載器。圖右邊的桔×××文字表示各類(lèi)加載器對(duì)應(yīng)的加載目錄。啟動(dòng)類(lèi)加載器加載java home中l(wèi)ib目錄下的類(lèi),擴(kuò)展加載器負(fù)責(zé)加載ext目錄下的類(lèi),應(yīng)用加載器加載classpath指定目錄下的類(lèi)。

除此之外,可以自定義類(lèi)加載器。

java的類(lèi)加載使用雙親委派模式,即一個(gè)類(lèi)加載器在加載類(lèi)時(shí),先把這個(gè)請(qǐng)求委托給自己的父類(lèi)加載器去執(zhí)行,如果父類(lèi)加載器還存在父類(lèi)加載器,就繼續(xù)向上委托,直到頂層的啟動(dòng)類(lèi)加載器,如圖中藍(lán)色向上的箭頭。如果父類(lèi)加載器能夠完成類(lèi)加載,就成功返回,如果父類(lèi)加載器無(wú)法完成加載,那么子加載器才會(huì)嘗試自己去加載。

這種雙親委派模式的好處,一個(gè)可以避免類(lèi)的重復(fù)加載,另外也避免了java的核心API被篡改。

三、其他知識(shí)梳理

1.詳解分代回收? ???

前面提到過(guò),java的堆內(nèi)存被分代管理,分代管理主要是為了方便垃圾回收,這樣做基于2個(gè)事實(shí),第一、大部分對(duì)象很快就不再使用,第二,還有一部分不會(huì)立即無(wú)用,但也不會(huì)持續(xù)很長(zhǎng)時(shí)間。

虛擬機(jī)中劃分為年輕代、老年代、和永久代。

1>年輕代:主要用來(lái)存放新創(chuàng)建的對(duì)象,年輕代分為eden區(qū)和兩個(gè)Survivor區(qū)。大部分對(duì)象在Eden區(qū)中生成。當(dāng)Eden區(qū)滿(mǎn)時(shí),還存活的對(duì)象會(huì)在兩個(gè)Survivor區(qū)交替保存,達(dá)到一定次數(shù)的對(duì)象會(huì)晉升到老年代。

2>老年代:用來(lái)存放從年輕代晉升而來(lái)的,存活時(shí)間較長(zhǎng)的對(duì)象。

3>永久代:主要保存類(lèi)信息等內(nèi)容,這里的永久代是指對(duì)象劃分方式,不是專(zhuān)指1.7的permGen,或者1.8之后的metaspace。

根據(jù)年輕代與老年代的特點(diǎn),jvm提供了不同的垃圾回收算法。垃圾回收算法按類(lèi)型可以分為引用計(jì)數(shù)法、復(fù)制法和標(biāo)記清除法。

其中引用計(jì)數(shù)法是通過(guò)對(duì)象被引用的次數(shù)來(lái)確定對(duì)象是否被使用,缺點(diǎn)是無(wú)法解決循環(huán)引用的問(wèn)題。

復(fù)制算法需要from和to兩塊相同大小的內(nèi)存空間,對(duì)象分配時(shí)只在from塊中進(jìn)行,回收時(shí)把存活對(duì)象復(fù)制到to塊中,并清空f(shuō)rom塊,然后交換兩塊的分工,即把from塊作為to塊,把to塊作為from塊。缺點(diǎn)是內(nèi)存使用率較低。

標(biāo)記清除算法分為標(biāo)記對(duì)象和清除不在使用的對(duì)象兩個(gè)階段,標(biāo)記清除算法的缺點(diǎn)是會(huì)產(chǎn)生內(nèi)存碎片。

jvm中提供的年輕代回收算法Serial、ParNew、Parallel Scavenge都是復(fù)制算法,而CMS、G1、zgc都屬于標(biāo)記清除算法。

本篇文章,對(duì)這幾個(gè)算法就不展開(kāi)了

?

總結(jié):面試考察點(diǎn)及加分項(xiàng)

1.jvm相關(guān)的面試考察點(diǎn)

首先,需要jvm的內(nèi)存模型和java的內(nèi)存模型;

其次,要了解的類(lèi)的加載過(guò)程,了解雙親委派機(jī)制;

第三,要理解內(nèi)存的可見(jiàn)性與java內(nèi)存模型對(duì)原子性、可見(jiàn)性、有序性的保證機(jī)制;

第四,要了解常用的gc算法的特點(diǎn)、執(zhí)行過(guò)程,和適用場(chǎng)景,例如g1適合對(duì)最大延遲有要求的場(chǎng)合,zgc適用于64為系統(tǒng)的大內(nèi)存服務(wù)中;

第五,要了解常用的jvm參數(shù),明白對(duì)不同參數(shù)的調(diào)整會(huì)有怎樣的影響,適用什么樣的場(chǎng)景。例如垃圾回收的并發(fā)數(shù)、偏向鎖設(shè)置等

2.相關(guān)加分項(xiàng)

如果想要面試官對(duì)你留下更好的印象的話(huà),注意這些加分項(xiàng):?

  • 首先,如果在編譯器優(yōu)化方面有深入的了解的話(huà),會(huì)讓面試官覺(jué)得你對(duì)技術(shù)的深度比較有追求。例如知道在編程時(shí)如何合理利用棧上分配降低gc壓力、如何編寫(xiě)適合內(nèi)聯(lián)優(yōu)化等代碼等。

  • 其次,如果你能有線(xiàn)上實(shí)際問(wèn)題的排查經(jīng)驗(yàn)或思路那就更好了,面試官都喜歡動(dòng)手能力強(qiáng)的同學(xué)。例如解決過(guò)線(xiàn)上經(jīng)常full gc問(wèn)題,排查過(guò)內(nèi)存泄露問(wèn)題等。

  • 第三,如果能有針對(duì)特定場(chǎng)景的jvm優(yōu)化實(shí)踐或者優(yōu)化思路,也會(huì)有意想不到的效果。例如針對(duì)高并發(fā)低延遲的場(chǎng)景,如何調(diào)整gc參數(shù)盡量降低gc停頓時(shí)間,針對(duì)隊(duì)列處理機(jī)如何盡可能提高吞吐率等;

  • 第四,如果對(duì)最新的jvm技術(shù)趨勢(shì)有所了解,也會(huì)給面試官留下比較深刻的印象。例如了解zgc高效的實(shí)現(xiàn)原理,了解Graalvm的特點(diǎn)等。

總之,掌握以上具體的JVM考點(diǎn),才能在面試時(shí)應(yīng)答自如。希望讀完此篇文章的你,能做好準(zhǔn)備,拿到心儀的Offer。


文末彩蛋

針對(duì)于上面所涉及到的知識(shí)點(diǎn)我總結(jié)出了有1到5年開(kāi)發(fā)經(jīng)驗(yàn)的程序員在面試中涉及到的絕大部分架構(gòu)面試題及答案做成了文檔和架構(gòu)視頻資料免費(fèi)分享給大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并發(fā)等架構(gòu)技術(shù)資料),希望能幫助到您面試前的復(fù)習(xí)且找到一個(gè)好的工作,也節(jié)省大家在網(wǎng)上搜索資料的時(shí)間來(lái)學(xué)習(xí),也可以關(guān)注我一下以后會(huì)有更多干貨分享。

資料獲取方式 QQ群搜索“708-701-457” 即可免費(fèi)領(lǐng)取

95%的技術(shù)面試必考的JVM知識(shí)點(diǎn)都在這,另附加分思路!
95%的技術(shù)面試必考的JVM知識(shí)點(diǎn)都在這,另附加分思路!
95%的技術(shù)面試必考的JVM知識(shí)點(diǎn)都在這,另附加分思路!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI