熬夜肝25道面試必問(wèn)JVM面試題(含面試答案蟀俊,強(qiáng)烈介意收藏)

1、JVM 整體組成

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

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

2、JVM內(nèi)存分哪幾個(gè)區(qū),每個(gè)區(qū)的作用是什么?

方法區(qū):

  1. 有時(shí)候也成為永久代此衅,在該區(qū)內(nèi)很少發(fā)生垃圾回收,但是并不代表不發(fā)生GC亭螟,在這里進(jìn)行的GC主要是對(duì)方法區(qū)里的常量池和對(duì)類型的卸載
  2. 方法區(qū)主要用來(lái)存儲(chǔ)已被虛擬機(jī)加載的類的信息挡鞍、常量、靜態(tài)變量和即時(shí)編譯器編譯后的代碼等數(shù)據(jù)预烙。
  3. 該區(qū)域是被線程共享的墨微。
  4. 方法區(qū)里有一個(gè)運(yùn)行時(shí)常量池,用于存放靜態(tài)編譯產(chǎn)生的字面量和符號(hào)引用扁掸。該常量池具有動(dòng)態(tài)性欢嘿,也就是說(shuō)常量并不一定是編譯時(shí)確定,運(yùn)行時(shí)生成的常量也會(huì)存在這個(gè)常量池中也糊。

虛擬機(jī)棧:

  1. 虛擬機(jī)棧也就是我們平常所稱的棧內(nèi)存,它為java方法服務(wù)炼蹦,每個(gè)方法在執(zhí)行的時(shí)候都會(huì)創(chuàng)建一個(gè)棧幀,用于存儲(chǔ)局部變量表狸剃、操作數(shù)棧掐隐、動(dòng)態(tài)鏈接和方法出口等信息。
  2. 虛擬機(jī)棧是線程私有的,它的生命周期與線程相同虑省。
  3. 局部變量表里存儲(chǔ)的是基本數(shù)據(jù)類型匿刮、returnAddress類型(指向一條字節(jié)碼指令的地址)和對(duì)象引用,這個(gè)對(duì)象引用有可能是指向?qū)ο笃鹗嫉刂返囊粋€(gè)指針探颈,也有可能是代表對(duì)象的句柄或者與對(duì)象相關(guān)聯(lián)的位置熟丸。局部變量所需的內(nèi)存空間在編譯器間確定
  4. 操作數(shù)棧的作用主要用來(lái)存儲(chǔ)運(yùn)算結(jié)果以及運(yùn)算的操作數(shù),它不同于局部變量表通過(guò)索引來(lái)訪問(wèn)伪节,而是壓棧和出棧的方式
  5. 每個(gè)棧幀都包含一個(gè)指向運(yùn)行時(shí)常量池中該棧幀所屬方法的引用光羞,持有這個(gè)引用是為了支持方法調(diào)用過(guò)程中的動(dòng)態(tài)連接.動(dòng)態(tài)鏈接就是將常量池中的符號(hào)引用在運(yùn)行期轉(zhuǎn)化為直接引用。

本地方法棧

本地方法棧和虛擬機(jī)棧類似怀大,只不過(guò)本地方法棧為Native方法服務(wù)纱兑。

java堆是所有線程所共享的一塊內(nèi)存,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建化借,幾乎所有的對(duì)象實(shí)例都在這里創(chuàng)建潜慎,因此該區(qū)域經(jīng)常發(fā)生垃圾回收操作。

程序計(jì)數(shù)器

內(nèi)存空間小蓖康,字節(jié)碼解釋器工作時(shí)通過(guò)改變這個(gè)計(jì)數(shù)值可以選取下一條需要執(zhí)行的字節(jié)碼指令铐炫,分支、循環(huán)蒜焊、跳轉(zhuǎn)倒信、異常處理和線程恢復(fù)等功能都需要依賴這個(gè)計(jì)數(shù)器完成。該內(nèi)存區(qū)域是唯一一個(gè)java虛擬機(jī)規(guī)范沒(méi)有規(guī)定任何OOM情況的區(qū)域山涡。

3堤结、什么情況下會(huì)發(fā)生棧內(nèi)存溢出唆迁?

  1. 棧是線程私有的鸭丛,棧的生命周期和線程一樣,每個(gè)方法在執(zhí)行的時(shí)候就會(huì)創(chuàng)建一個(gè)棧幀唐责,它包含局部變量表鳞溉、操作數(shù)棧、動(dòng)態(tài)鏈接鼠哥、方法出口等信息熟菲,局部變量表又包括基本數(shù)據(jù)類型和對(duì)象的引用;
  2. 當(dāng)線程請(qǐng)求的棧深度超過(guò)了虛擬機(jī)允許的最大深度時(shí)朴恳,會(huì)拋出StackOverFlowError異常抄罕,方法遞歸調(diào)用肯可能會(huì)出現(xiàn)該問(wèn)題
  3. 調(diào)整參數(shù)-xss去調(diào)整jvm棧的大小

4、如和判斷一個(gè)對(duì)象是否存活?(或者GC對(duì)象的判定方法)

判斷一個(gè)對(duì)象是否存活有兩種方法:

引用計(jì)數(shù)法

所謂引用計(jì)數(shù)法就是給每一個(gè)對(duì)象設(shè)置一個(gè)引用計(jì)數(shù)器于颖,每當(dāng)有一個(gè)地方引用這個(gè)對(duì)象時(shí)呆贿,就將計(jì)數(shù)器加一,引用失效時(shí),計(jì)數(shù)器就減一做入。當(dāng)一個(gè)對(duì)象的引用計(jì)數(shù)器為零時(shí)冒晰,說(shuō)明此對(duì)象沒(méi)有被引用,也就是“死對(duì)象”,將會(huì)被垃圾回收.
引用計(jì)數(shù)法有一個(gè)缺陷就是無(wú)法解決循環(huán)引用問(wèn)題竟块,也就是說(shuō)當(dāng)對(duì)象A引用對(duì)象B壶运,對(duì)象B又引用者對(duì)象A,那么此時(shí)A,B對(duì)象的引用計(jì)數(shù)器都不為零浪秘,也就造成無(wú)法完成垃圾回收蒋情,所以主流的虛擬機(jī)都沒(méi)有采用這種算法。

可達(dá)性算法(引用鏈法)

該算法的思想是:從一個(gè)被稱為GC Roots的對(duì)象開(kāi)始向下搜索秫逝,如果一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連時(shí)恕出,則說(shuō)明此對(duì)象不可用。

在java中可以作為GC Roots的對(duì)象有以下幾種:

  • 虛擬機(jī)棧中引用的對(duì)象
  • 方法區(qū)類靜態(tài)屬性引用的對(duì)象
  • 方法區(qū)常量池引用的對(duì)象
  • 本地方法棧JNI引用的對(duì)象

雖然這些算法可以判定一個(gè)對(duì)象是否能被回收违帆,但是當(dāng)滿足上述條件時(shí)浙巫,一個(gè)對(duì)象比不一定會(huì)被回收。當(dāng)一個(gè)對(duì)象不可達(dá)GC Root時(shí)刷后,這個(gè)對(duì)象并 不會(huì)立馬被回收的畴,而是出于一個(gè)死緩的階段,若要被真正的回收需要經(jīng)歷兩次標(biāo)記

如果對(duì)象在可達(dá)性分析中沒(méi)有與GC Root的引用鏈尝胆,那么此時(shí)就會(huì)被第一次標(biāo)記并且進(jìn)行一次篩選丧裁,篩選的條件是是否有必要執(zhí)行finalize()方法。當(dāng)對(duì)象沒(méi)有覆蓋finalize()方法或者已被虛擬機(jī)調(diào)用過(guò)含衔,那么就認(rèn)為是沒(méi)必要的煎娇。

如果該對(duì)象有必要執(zhí)行finalize()方法,那么這個(gè)對(duì)象將會(huì)放在一個(gè)稱為F-Queue的對(duì)隊(duì)列中贪染,虛擬機(jī)會(huì)觸發(fā)一個(gè)Finalize()線程去執(zhí)行缓呛,此線程是低優(yōu)先級(jí)的,并且虛擬機(jī)不會(huì)承諾一直等待它運(yùn)行完杭隙,這是因?yàn)槿绻鹒inalize()執(zhí)行緩慢或者發(fā)生了死鎖哟绊,那么就會(huì)造成F-Queue隊(duì)列一直等待,造成了內(nèi)存回收系統(tǒng)的崩潰痰憎。GC對(duì)處于F-Queue中的對(duì)象進(jìn)行第二次被標(biāo)記票髓,這時(shí),該對(duì)象將被移除”即將回收”集合铣耘,等待回收洽沟。

5、JVM中一次完整的GC是什么樣子的蜗细?對(duì)象如何晉升到老年代裆操?

  • java堆 = 新生代+老年代;
  • 新生代 = Eden + Suivivor(S0 + S1),默認(rèn)分配比例是8:1:1;
  • 當(dāng)Eden區(qū)空間滿了的時(shí)候跷车,就會(huì)觸發(fā)一次Minor GC棘利,以收集新生代的垃圾,存活下來(lái)的對(duì)象會(huì)被分配到Survivor區(qū)
  • 大對(duì)象(需要大量連續(xù)內(nèi)存空間的對(duì)象)會(huì)直接被分配到老年代
  • 如果對(duì)象在Eden中出生朽缴,并且在經(jīng)歷過(guò)一次Minor GC之后仍然存活善玫,被分配到存活區(qū)的話,年齡+1密强,此后每經(jīng)歷過(guò)一次Minor GC并且存活下來(lái)茅郎,年齡就+1,當(dāng)年齡達(dá)到15的時(shí)候或渤,會(huì)被晉升到老年代系冗;
  • 當(dāng)老年代滿了,而無(wú)法容納更多對(duì)象的話薪鹦,會(huì)觸發(fā)一次full gc掌敬;full gc存儲(chǔ)的是整個(gè)內(nèi)存堆(包括年輕代和老年代);池磁;
  • Major GC是發(fā)生在老年代的GC奔害,清理老年區(qū),經(jīng)常會(huì)伴隨至少一次minor gc地熄;

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

  1. 程序計(jì)數(shù)器(Program Counter Register)
  2. Java虛擬機(jī)棧(Java Virtual Machine Stacks)
  3. 本地方法棧(Native Method Stack)
  4. Java堆(Java Heap)
  5. 方法區(qū)(Methed Area)

7、java中會(huì)存在內(nèi)存泄漏嗎端考?請(qǐng)簡(jiǎn)單描述

會(huì)雅潭。自己實(shí)現(xiàn)堆載的數(shù)據(jù)結(jié)構(gòu)時(shí)有可能會(huì)出現(xiàn)內(nèi)存泄露。

8却特、簡(jiǎn)述java垃圾回收機(jī)制?

在java中扶供,程序員是不需要顯示的去釋放一個(gè)對(duì)象的內(nèi)存的,而是由虛擬機(jī)自行執(zhí)行核偿。在JVM中诚欠,有一個(gè)垃圾回收線程顽染,它是低優(yōu)先級(jí)的漾岳,在正常情況下是不會(huì)執(zhí)行的,只有在虛擬機(jī)空閑或者當(dāng)前堆內(nèi)存不足時(shí)粉寞,才會(huì)觸發(fā)執(zhí)行尼荆,掃面那些沒(méi)有被任何引用的對(duì)象,并將它們添加到要回收的集合中唧垦,進(jìn)行回收捅儒。

9、Serial 與 Parallel GC 之間的不同之處?

Serial 與 Parallel 在 GC 執(zhí)行的時(shí)候都會(huì)引起 stop-the-world巧还。它們之間主要不同 serial 收集器是默認(rèn)的復(fù)制收集器鞭莽,執(zhí)行 GC 的時(shí)候只有一個(gè)線程,而parallel 收集器使用多個(gè) GC 線程來(lái)執(zhí)行麸祷。

10澎怒、Java中的垃圾回收算法?

java中有四種垃圾回收算法阶牍,分別是標(biāo)記清除法喷面、標(biāo)記整理法、復(fù)制算法走孽、分代收集算法惧辈;

標(biāo)記清除法:

第一步:利用可達(dá)性去遍歷內(nèi)存,把存活對(duì)象和垃圾對(duì)象進(jìn)行標(biāo)記磕瓷;
第二步:在遍歷一遍盒齿,將所有標(biāo)記的對(duì)象回收掉;
特點(diǎn):效率不行困食,標(biāo)記和清除的效率都不高县昂;標(biāo)記和清除后會(huì)產(chǎn)生大量的不連續(xù)的空間分片,可能會(huì)導(dǎo)致之后程序運(yùn)行的時(shí)候需分配大對(duì)象而找不到連續(xù)分片而不得不觸發(fā)一次GC陷舅;

標(biāo)記整理法:

第一步:利用可達(dá)性去遍歷內(nèi)存倒彰,把存活對(duì)象和垃圾對(duì)象進(jìn)行標(biāo)記;
第二步:將所有的存活的對(duì)象向一段移動(dòng)莱睁,將端邊界以外的對(duì)象都回收掉待讳;
特點(diǎn):適用于存活對(duì)象多,垃圾少的情況仰剿;需要整理的過(guò)程创淡,無(wú)空間碎片產(chǎn)生;

復(fù)制算法:

將內(nèi)存按照容量大小分為大小相等的兩塊南吮,每次只使用一塊琳彩,當(dāng)一塊使用完了,就將還存活的對(duì)象移到另一塊上部凑,然后在把使用過(guò)的內(nèi)存空間移除露乏;
特點(diǎn):不會(huì)產(chǎn)生空間碎片;內(nèi)存使用率極低涂邀;

分代收集算法:

根據(jù)內(nèi)存對(duì)象的存活周期不同瘟仿,將內(nèi)存劃分成幾塊,java虛擬機(jī)一般將內(nèi)存分成新生代和老生代比勉,在新生代中劳较,有大量對(duì)象死去和少量對(duì)象存活驹止,所以采用復(fù)制算法,只需要付出少量存活對(duì)象的復(fù)制成本就可以完成收集观蜗;老年代中因?yàn)閷?duì)象的存活率極高臊恋,沒(méi)有額外的空間對(duì)他進(jìn)行分配擔(dān)保,所以采用標(biāo)記清理或者標(biāo)記整理算法進(jìn)行回收墓捻;

11捞镰、怎樣通過(guò) Java 程序來(lái)判斷 JVM 是 32 位 還是 64位?

你可以檢查某些系統(tǒng)屬性如 sun.arch.data.model 或 os.arch 來(lái)獲取該信息毙替。

12岸售、java中垃圾收集的方法有哪些?

  • 標(biāo)記-清除:

這是垃圾收集算法中最基礎(chǔ)的,根據(jù)名字就可以知道厂画,它的思想就是標(biāo)記哪些要被回收的對(duì)象凸丸,然后統(tǒng)一回收。這種方法很簡(jiǎn)單袱院,但是會(huì)有兩個(gè)主要問(wèn)題:1.效率不高屎慢,標(biāo)記和清除的效率都很低;2.會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片忽洛,導(dǎo)致以后程序在分配較大的對(duì)象時(shí)腻惠,由于沒(méi)有充足的連續(xù)內(nèi)存而提前觸發(fā)一次GC動(dòng)作。

  • 復(fù)制算法:

為了解決效率問(wèn)題欲虚,復(fù)制算法將可用內(nèi)存按容量劃分為相等的兩部分集灌,然后每次只使用其中的一塊,當(dāng)一塊內(nèi)存用完時(shí)复哆,就將還存活的對(duì)象復(fù)制到第二塊內(nèi)存上欣喧,然后一次性清楚完第一塊內(nèi)存,再將第二塊上的對(duì)象復(fù)制到第一塊梯找。但是這種方式唆阿,內(nèi)存的代價(jià)太高,每次基本上都要浪費(fèi)一般的內(nèi)存锈锤。

于是將該算法進(jìn)行了改進(jìn)驯鳖,內(nèi)存區(qū)域不再是按照1:1去劃分,而是將內(nèi)存劃分為8:1:1三部分久免,較大那份內(nèi)存交Eden區(qū)浅辙,其余是兩塊較小的內(nèi)存區(qū)叫Survior區(qū)。每次都會(huì)優(yōu)先使用Eden區(qū)妄壶,若Eden區(qū)滿摔握,就將對(duì)象復(fù)制到第二塊內(nèi)存區(qū)上寄狼,然后清除Eden區(qū)丁寄,如果此時(shí)存活的對(duì)象太多氨淌,以至于Survivor不夠時(shí),會(huì)將這些對(duì)象通過(guò)分配擔(dān)保機(jī)制復(fù)制到老年代中伊磺。(java堆又分為新生代和老年代)

  • 標(biāo)記-整理

該算法主要是為了解決標(biāo)記-清除盛正,產(chǎn)生大量?jī)?nèi)存碎片的問(wèn)題;當(dāng)對(duì)象存活率較高時(shí)屑埋,也解決了復(fù)制算法的效率問(wèn)題豪筝。它的不同之處就是在清除對(duì)象的時(shí)候現(xiàn)將可回收對(duì)象移動(dòng)到一端,然后清除掉端邊界以外的對(duì)象摘能,這樣就不會(huì)產(chǎn)生內(nèi)存碎片了续崖。

  • 分代收集:

現(xiàn)在的虛擬機(jī)垃圾收集大多采用這種方式,它根據(jù)對(duì)象的生存周期团搞,將堆分為新生代和老年代严望。在新生代中,由于對(duì)象生存期短逻恐,每次回收都會(huì)有大量對(duì)象死去像吻,那么這時(shí)就采用復(fù)制算法。老年代里的對(duì)象存活率較高复隆,沒(méi)有額外的空間進(jìn)行分配擔(dān)保拨匆,所以可以使用標(biāo)記-整理 或者 標(biāo)記-清除。

13挽拂、如何判斷一個(gè)對(duì)象是否應(yīng)該被回收惭每?

判斷對(duì)象是否存活一般有兩種方式:

  • 引用計(jì)數(shù):每個(gè)對(duì)象有一個(gè)引用計(jì)數(shù)屬性,新增一個(gè)引用時(shí)計(jì)數(shù)加1亏栈,引用釋放時(shí)計(jì)數(shù)減1洪鸭,計(jì)數(shù)為0時(shí)可以回收。此方法簡(jiǎn)單仑扑,無(wú)法解決對(duì)象相互循環(huán)引用的問(wèn)題览爵。
  • 可達(dá)性分析(Reachability Analysis):從GC Roots開(kāi)始向下搜索,搜索所走過(guò)的路徑稱為引用鏈镇饮。當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連時(shí)蜓竹,則證明此對(duì)象是不可用的,不可達(dá)對(duì)象储藐。

14俱济、調(diào)優(yōu)命令

Sun JDK監(jiān)控和故障處理命令有jps jstat jmap jhat jstack jinfo

  • jps,JVM Process Status Tool,顯示指定系統(tǒng)內(nèi)所有的HotSpot虛擬機(jī)進(jìn)程钙勃。
  • jstat蛛碌,JVM statistics Monitoring是用于監(jiān)視虛擬機(jī)運(yùn)行時(shí)狀態(tài)信息的命令,它可以顯示出虛擬機(jī)進(jìn)程中的類裝載辖源、內(nèi)存蔚携、垃圾收集希太、JIT編譯等運(yùn)行數(shù)據(jù)。
  • jmap酝蜒,JVM Memory Map命令用于生成heap dump文件
  • jhat誊辉,JVM Heap Analysis Tool命令是與jmap搭配使用,用來(lái)分析jmap生成的dump亡脑,jhat內(nèi)置了一個(gè)微型的HTTP/HTML服務(wù)器堕澄,生成dump的分析結(jié)果后,可以在瀏覽器中查看
  • jstack霉咨,用于生成java虛擬機(jī)當(dāng)前時(shí)刻的線程快照蛙紫。
  • jinfo,JVM Configuration info 這個(gè)命令作用是實(shí)時(shí)查看和調(diào)整虛擬機(jī)運(yùn)行參數(shù)途戒。

15惊来、JRE、JDK棺滞、JVM 及 JIT 之間有什么不同裁蚁?

  • JRE 代表 Java 運(yùn)行時(shí)(Java run-time),是運(yùn)行 Java 引用所必須的继准。
  • JDK 代表 Java 開(kāi)發(fā)工具(Java development kit)枉证,是 Java 程序打開(kāi)發(fā)工具,如 Java編譯器移必,它也包含 JRE室谚。
  • JVM 代表 Java 虛擬機(jī)(Java virtual machine),它的責(zé)任是運(yùn)行 Java 應(yīng)用崔泵。JIT 代表即時(shí)編譯(Just In Time compilation)秒赤,當(dāng)代碼執(zhí)行的次數(shù)超過(guò)一定的閾值時(shí),會(huì)將 Java 字節(jié)碼轉(zhuǎn)換為本地代碼憎瘸,如入篮,主要的熱點(diǎn)代碼會(huì)被準(zhǔn)換為本地代碼,這樣有利大幅度提高 Java 應(yīng)用的性能幌甘。

16潮售、如何判斷一個(gè)對(duì)象是否存活?

判斷一個(gè)對(duì)象是否存活锅风,分為兩種算法1:引用計(jì)數(shù)法酥诽;2:可達(dá)性分析算法;

  • 引用計(jì)數(shù)法:

給每一個(gè)對(duì)象設(shè)置一個(gè)引用計(jì)數(shù)器皱埠,當(dāng)有一個(gè)地方引用該對(duì)象的時(shí)候肮帐,引用計(jì)數(shù)器就+1,引用失效時(shí)边器,引用計(jì)數(shù)器就-1训枢;當(dāng)引用計(jì)數(shù)器為0的時(shí)候托修,就說(shuō)明這個(gè)對(duì)象沒(méi)有被引用,也就是垃圾對(duì)象肮砾,等待回收诀黍;
缺點(diǎn):無(wú)法解決循環(huán)引用的問(wèn)題袋坑,當(dāng)A引用B仗处,B也引用A的時(shí)候,此時(shí)AB對(duì)象的引用都不為0枣宫,此時(shí)也就無(wú)法垃圾回收婆誓,所以一般主流虛擬機(jī)都不采用這個(gè)方法;

  • 可達(dá)性分析法

從一個(gè)被稱為GC Roots的對(duì)象向下搜索也颤,如果一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連接時(shí)洋幻,說(shuō)明此對(duì)象不可用,在java中可以作為GC Roots的對(duì)象有以下幾種:

  1. 虛擬機(jī)棧中引用的對(duì)象
  2. 方法區(qū)類靜態(tài)屬性引用的變量
  3. 方法區(qū)常量池引用的對(duì)象
  4. 本地方法棧JNI引用的對(duì)象

但一個(gè)對(duì)象滿足上述條件的時(shí)候翅娶,不會(huì)馬上被回收文留,還需要進(jìn)行兩次標(biāo)記;第一次標(biāo)記:判斷當(dāng)前對(duì)象是否有finalize()方法并且該方法沒(méi)有被執(zhí)行過(guò)竭沫,若不存在則標(biāo)記為垃圾對(duì)象燥翅,等待回收;若有的話蜕提,則進(jìn)行第二次標(biāo)記森书;第二次標(biāo)記將當(dāng)前對(duì)象放入F-Queue隊(duì)列,并生成一個(gè)finalize線程去執(zhí)行該方法谎势,虛擬機(jī)不保證該方法一定會(huì)被執(zhí)行凛膏,這是因?yàn)槿绻€程執(zhí)行緩慢或進(jìn)入了死鎖,會(huì)導(dǎo)致回收系統(tǒng)的崩潰脏榆;如果執(zhí)行了finalize方法之后仍然沒(méi)有與GC Roots有直接或者間接的引用猖毫,則該對(duì)象會(huì)被回收;

17须喂、有哪幾種垃圾回收器鄙麦,有哪些優(yōu)缺點(diǎn)?cms和g1的區(qū)別镊折?

垃圾回收器主要分為以下幾種:Serial胯府、ParNew、Parallel Scavenge恨胚、Serial Old骂因、Parallel Old、CMS赃泡、G1寒波;

  • Serial:

單線程的收集器乘盼,收集垃圾時(shí),必須stop the world俄烁,使用復(fù)制算法绸栅。

  • ParNew:

Serial收集器的多線程版本,也需要stop the world页屠,復(fù)制算法.

  • Parallel Scavenge:

新生代收集器粹胯,復(fù)制算法的收集器,并發(fā)的多線程收集器辰企,目標(biāo)是達(dá)到一個(gè)可控的吞吐量风纠,和ParNew的最大區(qū)別是GC自動(dòng)調(diào)節(jié)策略;虛擬機(jī)會(huì)根據(jù)系統(tǒng)的運(yùn)行狀態(tài)收集性能監(jiān)控信息牢贸,動(dòng)態(tài)設(shè)置這些參數(shù)竹观,以提供最優(yōu)停頓時(shí)間和最高的吞吐量;

  • Serial Old:

Serial收集器的老年代版本潜索,單線程收集器臭增,使用標(biāo)記整理算法。

  • Parallel Old:

是Parallel Scavenge收集器的老年代版本竹习,使用多線程誊抛,標(biāo)記-整理算法。

  • CMS:

是一種以獲得最短回收停頓時(shí)間為目標(biāo)的收集器由驹,標(biāo)記清除算法芍锚,運(yùn)作過(guò)程:初始標(biāo)記,并發(fā)標(biāo)記蔓榄,重新標(biāo)記并炮,并發(fā)清除,收集結(jié)束會(huì)產(chǎn)生大量空間碎片甥郑;

  • G1:

標(biāo)記整理算法實(shí)現(xiàn)逃魄,運(yùn)作流程主要包括以下:初始標(biāo)記,并發(fā)標(biāo)記澜搅,最終標(biāo)記伍俘,篩選回收。不會(huì)產(chǎn)生空間碎片勉躺,可以精確地控制停頓癌瘾;

G1將整個(gè)堆分為大小相等的多個(gè)Region(區(qū)域),G1跟蹤每個(gè)區(qū)域的垃圾大小饵溅,在后臺(tái)維護(hù)一個(gè)優(yōu)先級(jí)列表妨退,每次根據(jù)允許的收集時(shí)間,優(yōu)先回收價(jià)值最大的區(qū)域,已達(dá)到在有限時(shí)間內(nèi)獲取盡可能高的回收效率咬荷;

18冠句、類加載器雙親委派模型機(jī)制?

當(dāng)一個(gè)類收到了類加載請(qǐng)求時(shí)幸乒,不會(huì)自己先去加載這個(gè)類懦底,而是將其委派給父類,由父類去加載罕扎,如果此時(shí)父類不能加載聚唐,反饋給子類,由子類去完成類的加載壳影。

19拱层、什么是類加載器弥臼,類加載器有哪些?

實(shí)現(xiàn)通過(guò)類的權(quán)限定名獲取該類的二進(jìn)制字節(jié)流的代碼塊叫做類加載器宴咧。

主要有一下四種類加載器:

  1. 啟動(dòng)類加載器(Bootstrap ClassLoader)用來(lái)加載java核心類庫(kù),無(wú)法被java程序直接引用径缅。
  2. 擴(kuò)展類加載器(extensions class loader):它用來(lái)加載 Java 的擴(kuò)展庫(kù)掺栅。Java 虛擬機(jī)的實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫(kù)目錄。該類加載器在此目錄里面查找并加載 Java 類纳猪。
  3. 系統(tǒng)類加載器(system class loader):它根據(jù) Java 應(yīng)用的類路徑(CLASSPATH)來(lái)加載 Java 類氧卧。一般來(lái)說(shuō),Java 應(yīng)用的類都是由它來(lái)完成加載的氏堤∩尘可以通過(guò) ClassLoader.getSystemClassLoader()來(lái)獲取它。
  4. 用戶自定義類加載器鼠锈,通過(guò)繼承 java.lang.ClassLoader類的方式實(shí)現(xiàn)闪檬。

20、調(diào)優(yōu)工具

常用調(diào)優(yōu)工具分為兩類,jdk自帶監(jiān)控工具:jconsole和jvisualvm购笆,第三方有:MAT(Memory Analyzer Tool)粗悯、GChisto。

  • jconsole同欠,Java Monitoring and Management Console是從java5開(kāi)始样傍,在JDK中自帶的java監(jiān)控和管理控制臺(tái),用于對(duì)JVM中內(nèi)存铺遂,線程和類等的監(jiān)控
  • jvisualvm衫哥,jdk自帶全能工具,可以分析內(nèi)存快照襟锐、線程快照撤逢;監(jiān)控內(nèi)存變化、GC變化等。
  • MAT笛质,Memory Analyzer Tool泉沾,一個(gè)基于Eclipse的內(nèi)存分析工具,是一個(gè)快速妇押、功能豐富的Java heap分析工具跷究,它可以幫助我們查找內(nèi)存泄漏和減少內(nèi)存消耗
  • GChisto,一款專業(yè)分析gc日志的工具

21敲霍、JVM永久代中會(huì)發(fā)生垃圾回收么

垃圾回收不會(huì)發(fā)生在永久代俊马,如果永久代滿了或者是超過(guò)了臨界值,會(huì)觸發(fā)完全垃圾回收(Full GC)肩杈。如果你仔細(xì)查看垃圾收集器的輸出信息柴我,就會(huì)發(fā)現(xiàn)永久代也是被回收的。這就是為什么正確的永久代大小對(duì)避免Full GC是非常重要的原因扩然。請(qǐng)參考下Java8:從永久代到元數(shù)據(jù)區(qū) (注:Java8中已經(jīng)移除了永久代艘儒,新加了一個(gè)叫做元數(shù)據(jù)區(qū)的native內(nèi)存區(qū))

22、JVM 內(nèi)存區(qū)域

VM 內(nèi)存區(qū)域主要分為線程私有區(qū)域【程序計(jì)數(shù)器夫偶、虛擬機(jī)棧界睁、本地方法區(qū)】、線程共享區(qū)域【JAVA 堆兵拢、方法區(qū)】翻斟、直接內(nèi)存。

線程私有數(shù)據(jù)區(qū)域生命周期與線程相同, 依賴用戶線程的啟動(dòng)/結(jié)束 而 創(chuàng)建/銷毀(在 Hotspot VM 內(nèi), 每個(gè)線程都與操作系統(tǒng)的本地線程直接映射, 因此這部分內(nèi)存區(qū)域的存/否跟隨本地線程的生/死對(duì)應(yīng))说铃。

線程共享區(qū)域隨虛擬機(jī)的啟動(dòng)/關(guān)閉而創(chuàng)建/銷毀访惜。

直接內(nèi)存并不是 JVM 運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分, 但也會(huì)被頻繁的使用: 在 JDK 1.4 引入的 NIO 提供了基于Channel與 Buffer的IO方式, 它可以使用Native函數(shù)庫(kù)直接分配堆外內(nèi)存, 然后使用DirectByteBuffer 對(duì)象作為這塊內(nèi)存的引用進(jìn)行操作(詳見(jiàn): Java I/O 擴(kuò)展), 這樣就避免了在 Java堆和 Native 堆中來(lái)回復(fù)制數(shù)據(jù), 因此在一些場(chǎng)景中可以顯著提高性能。

23腻扇、虛擬機(jī)棧(線程私有)

是描述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ò)程舌剂。

棧幀( Frame)是用來(lái)存儲(chǔ)數(shù)據(jù)和部分過(guò)程結(jié)果的數(shù)據(jù)結(jié)構(gòu),同時(shí)也被用來(lái)處理動(dòng)態(tài)鏈接(Dynamic Linking)暑椰、 方法返回值和異常分派(Dispatch Exception)霍转。 棧幀隨著方法調(diào)用而創(chuàng)建,隨著方法結(jié)束而銷毀——無(wú)論方法是正常完成還是異常完成(拋出了在方法內(nèi)未被捕獲的異常)都算作方法結(jié)束一汽。

24避消、引用的分類

  • 強(qiáng)引用:GC時(shí)不會(huì)被回收
  • 軟引用:描述有用但不是必須的對(duì)象低滩,在發(fā)生內(nèi)存溢出異常之前被回收
  • 弱引用:描述有用但不是必須的對(duì)象,在下一次GC時(shí)被回收
  • 虛引用(幽靈引用/幻影引用):無(wú)法通過(guò)虛引用獲得對(duì)象岩喷,用PhantomReference實(shí)現(xiàn)虛引用恕沫,虛引用用來(lái)在GC時(shí)返回一個(gè)通知。

25纱意、方法區(qū)/永久代(線程共享)

即我們常說(shuō)的永久代(Permanent Generation), 用于存儲(chǔ)被 JVM 加載的類信息婶溯、常量、靜態(tài)變量即偷霉、時(shí)編譯器編譯后的代碼等數(shù)據(jù).HotSpot VM把GC分代收集擴(kuò)展至方法區(qū), 即使用Java堆的永久代來(lái)實(shí)現(xiàn)方法區(qū), 這樣 HotSpot 的垃圾收集器就可以像管理 Java 堆一樣管理這部分內(nèi)存,而不必為方法區(qū)開(kāi)發(fā)專門(mén)的內(nèi)存管理器(永久帶的內(nèi)存回收的主要目標(biāo)是針對(duì)常量池的回收和類型的卸載, 因此收益一般很小) 迄委。

運(yùn)行時(shí)常量池(Runtime Constant Pool)是方法區(qū)的一部分。 Class 文件中除了有類的版本类少、字段叙身、方法、接口等描述等信息外硫狞,還有一項(xiàng)信息是常量池 (Constant Pool Table)信轿,用于存放編譯期生成的各種字面量和符號(hào)引用,這部分內(nèi)容將在類加載后存放到方法區(qū)的運(yùn)行時(shí)常量池中妓忍。 Java 虛擬機(jī)對(duì) Class 文件的每一部分(自然也包括常量池)的格式都有嚴(yán)格的規(guī)定虏两,每一個(gè)字節(jié)用于存儲(chǔ)哪種數(shù)據(jù)都必須符合規(guī)范上的要求愧旦,這樣才會(huì)被虛擬機(jī)認(rèn)可世剖、裝載和執(zhí)行吩跋。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末笆焰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子非竿,更是在濱河造成了極大的恐慌琼蚯,老刑警劉巖酬凳,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異遭庶,居然都是意外死亡宁仔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)峦睡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)翎苫,“玉大人,你說(shuō)我怎么就攤上這事榨了〖宓” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵龙屉,是天一觀的道長(zhǎng)呐粘。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么作岖? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任唆垃,我火速辦了婚禮,結(jié)果婚禮上痘儡,老公的妹妹穿的比我還像新娘降盹。我一直安慰自己,他們只是感情好谤辜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布蓄坏。 她就那樣靜靜地躺著,像睡著了一般丑念。 火紅的嫁衣襯著肌膚如雪涡戳。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,215評(píng)論 1 299
  • 那天脯倚,我揣著相機(jī)與錄音渔彰,去河邊找鬼。 笑死推正,一個(gè)胖子當(dāng)著我的面吹牛恍涂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播植榕,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼再沧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了尊残?” 一聲冷哼從身側(cè)響起炒瘸,我...
    開(kāi)封第一講書(shū)人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寝衫,沒(méi)想到半個(gè)月后顷扩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡慰毅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年隘截,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汹胃。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡婶芭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出统台,到底是詐尸還是另有隱情雕擂,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布贱勃,位于F島的核電站井赌,受9級(jí)特大地震影響谤逼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仇穗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一流部、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纹坐,春花似錦枝冀、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至谷誓,卻和暖如春绒障,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捍歪。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工户辱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人糙臼。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓庐镐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親变逃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子必逆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容