欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

2023跳槽最新面試題整理——JVM系列-創(chuàng)新互聯(lián)

今天是農(nóng)歷2022年臘月二十七了,和往常的春節(jié)假期、五一假期和十一假期一樣都是團(tuán)隊中堅持到最后的一個。沒幾天也要快過年了,我先提前向大家拜個早年——祝大家兔年大吉,新春快樂,財源滾滾,萬事如意。
今年從十一假期之后由于種種原因也沒有更新文章,今天最后一天,由于做其他的也沒有心情,那就老規(guī)劃——最后一天就自己靜下心來整理文章來和大家分享;再加上今年由于YQ放開,大家都在積蓄力量準(zhǔn)備明年跳槽,那今天我就開始給大家來持續(xù)更新面試題系列吧,這篇文章先來更新JVM系列,打算完整的給大家整理出面試問題重點(diǎn),然后再看時間是否充裕再來判斷是否給大家整理詳細(xì)問題答案。

創(chuàng)新互聯(lián)專注于企業(yè)成都營銷網(wǎng)站建設(shè)、網(wǎng)站重做改版、龍里網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5響應(yīng)式網(wǎng)站、商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為龍里等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。1、類加載機(jī)制 ??? 1.1、類加載過程

?類加載過程可以初步分成如下幾步:
?加載—>驗證—>準(zhǔn)備—>解析—>初始化
在這里插入圖片描述

  • 加載: 根據(jù)類的全限定類名從磁盤獲取類的二進(jìn)制字節(jié)流。
  • 驗證: 字節(jié)碼驗證、文件格式驗證、元數(shù)據(jù)驗證和符號引用驗證
  • 準(zhǔn)備: 靜態(tài)變量分配內(nèi)存并且賦予零值
  • 解析: 將在編譯階段的符號引用轉(zhuǎn)化為直接引用,直接指向其內(nèi)存地址
  • 初始化: 將解析過程中的零值更改為程序員賦值的值
1.2、類加載器分類

?類加載器分為:啟動類加載器、擴(kuò)展類加載器、應(yīng)用程序類加載器和自定義類加載器

  • 啟動類加載器(Bootstrap Class Loader): 加載< JAVA-HOME >\lib目錄下的文件
  • 擴(kuò)展類加載器(Extension Class Loader): 加載< JAVA-HOME >\lib\ext目錄下的文件
  • 應(yīng)用程序類加載器(Application Class Loader): 加載用戶類路徑下的所有類包,也就是用戶自己寫的類
  • 自定義類加載器(User Class Loader): 負(fù)責(zé)加載用戶自定義的類路徑下的類包
1.3、雙親委派機(jī)制

?雙親委派機(jī)制流程圖如下所示:
在這里插入圖片描述

? 1.3.1、雙親委派如何運(yùn)行

? ?? ?? 這段我就用大白話來給大家講解了哈。比如當(dāng)我自己寫的一個類需要加載的時候,它會先去應(yīng)用程序類加載器中看是否被加載過,發(fā)現(xiàn)沒有;然后交由應(yīng)用程序類加載器的父類擴(kuò)展類加載器看是否被加載過,發(fā)現(xiàn)也沒有;然后它就會交由擴(kuò)展類加載器的父類啟動類加載器加載,發(fā)現(xiàn)同樣也沒有,上面的這些交由父類加載器就是向上委托;此時會進(jìn)行向下指派,啟動類加載器指派給它的子類擴(kuò)展類加載器,擴(kuò)展類加載器指派給應(yīng)用程序類加載器,此時應(yīng)用程序類加載器沒有向下指派的了,那么就由應(yīng)用程序類加載器加載。
? ?? ?? 上面如果大家不太明白,你們可以根據(jù)我的上段所說的內(nèi)容去畫流程圖,那么大家在畫流程圖之后就完全明白了。

? 1.3.2、雙親委派這種機(jī)制好處

? ?? ?? 采用雙親委派機(jī)制加載主要有一下兩點(diǎn)好處:
? ?? ?? 1、保證沙箱安全;比如JDK中的java.lang.String中,如果我對這個類重寫了,那么是不生效的,因為它在走到啟動類加載器的時候發(fā)現(xiàn)已經(jīng)被加載了,那么就會直接返回,此時就保證了其安全。
? ?? ?? 2、防止重復(fù)加載

? 1.3.3、為什么在父類加載器沒有加載的時候為什么不自己加載,反而交給子類加載器加載?

? ?? ?? 如果直接直接在父類加載器加載,此時加載看著比較省事了,因為不需要再向下指派,但是在下一次需要加載的時候,又需要向上進(jìn)行查找,那么是比較麻煩的,所以直接進(jìn)行向下委派給子類加載器加載。

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

JVM運(yùn)行時數(shù)據(jù)區(qū)主要包括堆、虛擬機(jī)棧、方法區(qū)、本地方法棧和程序計數(shù)器。
運(yùn)行時數(shù)據(jù)區(qū)圖如下所示:
在這里插入圖片描述下面我詳細(xì)介紹下運(yùn)行時數(shù)據(jù)區(qū)各個部分其功能:

線程共享:

  • 堆: 主要存放new出來的對象,還有數(shù)組和JDK1.8存放字符串常量池;
  • 方法區(qū): 主要存放類信息、方法信息,靜態(tài)變量和常量池等等;

線程獨(dú)享:

  • 虛擬機(jī)棧: 虛擬機(jī)棧是由一個個棧幀組成,當(dāng)每調(diào)用一個方法時就是生成一個棧幀壓入虛擬機(jī)棧中,棧幀中包含局部變量、操作數(shù)棧、動態(tài)鏈接和方法出口;
  • 本地方法棧: 本地方法棧和虛擬機(jī)棧的原理一樣,只是虛擬機(jī)棧調(diào)用的是Java方法,但是本地方法棧調(diào)用的是本地方法(Native);
  • 程序計數(shù)器: 在Java程序運(yùn)行過程中,會發(fā)生線程上下文切換,當(dāng)線程重新獲得CPU時間片時,要保證從上次執(zhí)行的行數(shù)繼續(xù)執(zhí)行,那么程序計數(shù)器就是保證從原來位置繼續(xù)執(zhí)行;
3、JVM對象創(chuàng)建和內(nèi)存分配機(jī)制 ???????3.1、堆內(nèi)存結(jié)構(gòu)介紹

???堆內(nèi)存分為新生代和老年代,新生代:老年代=1:2;新生代中又分為Eden、S0和S1區(qū);Eden:S0:S1=8:1:1;
在這里插入圖片描述

3.2、對象創(chuàng)建流程

???類加載流程如下圖所示:
在這里插入圖片描述詳細(xì)介紹其每一步流程:
???1、加載: 當(dāng)new對象時,會根據(jù)雙親委派機(jī)制檢查下該類是否被加載過,如果沒有加載過則執(zhí)行類加載過程:加載—>驗證—>準(zhǔn)備—>解析—>初始化;
???2、分配內(nèi)存: 當(dāng)加載完成之后,接下來就要為新生的對象去分配內(nèi)存空間;當(dāng)類加載完成之后就知道了對象所需要內(nèi)存空間;就從堆中找出一塊對象所需要內(nèi)存空間大小的內(nèi)存給該對象;
??????????劃分內(nèi)存方法:
?????????????1、指針碰撞法: 如果Java堆中內(nèi)存是絕對規(guī)整的,所有用過的內(nèi)存都放在一邊,空閑的內(nèi)存放在另一邊,中間放著一個指針作為分界點(diǎn) 的指示器,那所分配內(nèi)存就僅僅是把那個指針向空閑空間那邊挪動一段與對象大小相等的距離。
?????????????2、空閑列表法: 如果Java堆中的內(nèi)存并不是規(guī)整的,已使用的內(nèi)存和空閑的內(nèi)存相互交錯,那就沒有辦法簡單地進(jìn)行指針碰撞了,虛擬機(jī)就必須維護(hù)一個列表,記錄上哪些內(nèi)存塊是可用的,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實(shí)例, 并更新列表上的記錄。
??????????解決并發(fā)分配內(nèi)存產(chǎn)生問題:
??????????在并發(fā)情況下,可能出現(xiàn)正在給對象A分配內(nèi)存,指針還沒來得及修改,對象B又同時使用了原來的指針來分配內(nèi)存的情況。
??????????CAS(compare and swap)法:
??????????虛擬機(jī)采用CAS配上失敗重試的方式保證更新操作的原子性來對分配內(nèi)存空間的動作進(jìn)行同步處理。
???3、初始化: 內(nèi)存分配完成后,虛擬機(jī)需要將分配到的內(nèi)存空間都初始化為零值(不包括對象頭),這一步操作保證了對象的實(shí)例字段在Java代碼中可以不賦初始值就直接使用,程序能訪問到這些字段的數(shù)據(jù)類型所對應(yīng)的零值。
注意: 這里的初始化和加載過程的初始化是不一樣的,加載的初始化是將static修飾的靜態(tài)變量賦予零值。
???4、設(shè)置對象頭: 初始化零值之后,要對對象做些必要設(shè)置,例如對象屬于哪個類的實(shí)例對象,GC年齡,對象hashcode和如何找到類的元數(shù)據(jù)信息等等。
???在虛擬機(jī)中,對象在內(nèi)存中布局分為三部分:對象頭、實(shí)例數(shù)據(jù)和對齊填充。
???對象頭主要包含兩部分信息:一部分是運(yùn)行時自身數(shù)據(jù):hash碼、GC年齡、偏向鎖ID,線程持有的鎖等等;另一部分是對象持有類的指針,即對象指向它類元數(shù)據(jù)的指針,虛擬機(jī)通過這個指針找到該對象歸屬于哪個類。
在這里插入圖片描述???5、執(zhí)行init()方法:
????????執(zhí)行方法,即對象按照程序員的意愿進(jìn)行初始化。對應(yīng)到語言層面上講,就是為屬性賦值(注意,這與上面的賦零值不同,這是由程序員賦的值),和執(zhí)行構(gòu)造方法。

3.3、對象內(nèi)存分配

???對象內(nèi)存分配流程圖如下所示:
在這里插入圖片描述
???一般我們認(rèn)為對象會直接分配到堆中新生代Eden區(qū)中,這是不對的,對象可能分配到虛擬機(jī)棧中,也有可能分配到堆中的老年代中,這都是可能發(fā)生的。下面我來介紹下這幾種情況

3.3.1、對象在棧上分配

???當(dāng)對象發(fā)生了逃逸分析時,那么此時對象就會直接分配到棧中,而不是分配到堆中。這樣做的目的是能夠減少GC的壓力,因為分配到棧中之后,會隨著調(diào)用這個方法結(jié)束而出棧銷毀。
???什么是逃逸分析?
???????這個通俗講就是我在方法內(nèi)部new一個對象后,該對象只在該方法中使用,不會讓方法以外的使用,那么此時就發(fā)生了逃逸分析。

3.3.2、對象在Eden區(qū)分配

???正常情況下大量的對象都是分配到堆中新生代的Eden區(qū)。

3.3.3、大對象直接分配至老年代

???當(dāng)我們創(chuàng)建的是大對象時,會直接分配到老年代中,這樣做的的目的減少它在新生代中每次GC來回復(fù)制,并且能減少觸發(fā)minor GC次數(shù)而引發(fā)的實(shí)際不是真正長時間存活的對象而存放老年代所引發(fā)的一系列問題。
???大對象是如何判斷的呢?
????????在JVM中設(shè)置-XX:PretenureSizeThreshold 可以設(shè)置大對象的大小

3.3.4、長期存活的對象進(jìn)入老年代

????這種也是正常的,當(dāng)對象創(chuàng)建之后放入堆中新生代的Eden區(qū),然后當(dāng)新生代滿了之后觸發(fā)minor GC,每次minor GC存活的對象,他們的對象頭的GC年齡就會+1,當(dāng)達(dá)到15次之后,就會講對象存放進(jìn)老年代,此時就是長期存活對象進(jìn)入老年代。

3.3.5、對象動態(tài)年齡判斷

????當(dāng)某一年齡的對象占Survivor區(qū)的一半以上時,那么他就會將大于等于它的GC年齡直接存放進(jìn)老年代中。

3.3.6、老年帶空間擔(dān)保機(jī)制

????當(dāng)觸發(fā)minor GC的時候都會去看下老年代的可用空間大小,如果老年代的可用空間大小大于等于新生代對象所有之和,那么可以直接觸發(fā)minor GC;否則會查看是否開啟了分配擔(dān)保機(jī)制,如果沒有開啟,那么會直接觸發(fā)full GC ,如果開啟了,就會看每次minor GC存活的對象平均大小是否小于等于老年代可用空間大小,如果滿足,則直接minor GC,否則觸發(fā)Full GC。
在這里插入圖片描述

4、垃圾收集 ???????4.1、如何判斷一個對象是否存活

判斷對象是否存活有兩種方式——計數(shù)器算法和可達(dá)性分析算法

???? 4.1.1、計數(shù)器算法

????????此方法比較簡單,每個對象就是專門有個計數(shù)的變量,當(dāng)該對象被引用一次就會+1;引用失效一次就會-1;當(dāng)計數(shù)變量為0時,代表該對象沒有被其他對象引用,可以被垃圾回收。
????????該方法有個弊端,就是當(dāng)兩個對象互相引用是,比如A對象引用B對象,B對象又引用A對象,他們之間不可能將計數(shù)器減為0,這就無法將對象進(jìn)行垃圾回收。

??????4.1.2、可達(dá)性分析算法

???????????將GC roots為起點(diǎn)向下遍歷,遍歷到的對象說明被其他引用,需要存活,沒有遍歷到的對象說明被引用,是垃圾對象,會被回收。
???????????GC roots根節(jié)點(diǎn)可以是靜態(tài)變量、局部變量等等
在這里插入圖片描述

4.2、垃圾收集算法

????垃圾收集算法主要有復(fù)制算法、標(biāo)記清除算法和標(biāo)記整理算法

????4.2.1、復(fù)制算法

????????效率比較高,主要是年輕代中使用該垃圾算法;它可以將內(nèi)存分為大小相同的兩塊,每次使用其中的一塊。當(dāng)這一塊的內(nèi)存使用完后,就將還存活的對象復(fù)制到另一塊去,然后再把使用的空間一次清理掉。這樣就使每次的內(nèi)存回收都是對內(nèi)存區(qū)間的一半進(jìn)行回收。
????特點(diǎn): 效率比較高,但是內(nèi)存利用率不高;每次只能利用50%的內(nèi)存
在這里插入圖片描述

????4.2.2、標(biāo)記清除算法

????算法分為“標(biāo)記”和“清除”階段:標(biāo)記存活的對象, 統(tǒng)一回收所有未被標(biāo)記的對象;
???? 特點(diǎn): 1、效率比較低(如果需要標(biāo)記的對象非常多,那么效率就會下降);2、空間利用率較高,但是會產(chǎn)生空間碎片化,導(dǎo)致大對象在存放時不能存放
在這里插入圖片描述

????4.2.3、標(biāo)記整理算法

???? 根據(jù)老年代的特點(diǎn)特出的一種標(biāo)記算法,標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣,但后續(xù)步驟不是直接對可回收對象回收,而是讓所有存活的對象向一端移動,然后直接清理掉端邊界以外的內(nèi)存。
在這里插入圖片描述

4.3、垃圾收集器

????常見的垃圾收集器有如下幾種:
在這里插入圖片描述
????如果說收集算法是內(nèi)存回收的方法論,那么垃圾收集器就是內(nèi)存回收的具體實(shí)現(xiàn)。

4.3.1、Serial收集器(-XX:+UseSerialGC -XX:+UseSerialOldGC)

?????????Serial(串行) 收集器是最基本、歷史最悠久的垃圾收集器了。大家看名字就知道這個收集器是一個單線程收集器了。它 的 “單線程” 的意義不僅僅意味著它只會使用一條垃圾收集線程去完成垃圾收集工作,更重要的是它在進(jìn)行垃圾收集工作的時候必須暫停其他所有的工作線程( “Stop The World” ),直到它收集結(jié)束。
在這里插入圖片描述
優(yōu)點(diǎn):
它簡單而高效(與其他收集器的單線程相比)。Serial 收集器由于沒有線程交互的開銷,自然可以獲得很高的單線程收集效率。
Serial Old收集器是Serial收集器的老年代版本,它同樣是一個單線程收集器。它主要有兩大用途:一種用途是在JDK1.5 以及以前的版本中與Parallel Scavenge收集器搭配使用,另一種用途是作為CMS收集器的后備方案 (當(dāng)CMS在垃圾收集時,垃圾回收的內(nèi)存遠(yuǎn)遠(yuǎn)不夠?qū)ο髣?chuàng)建所使用的內(nèi)存,那么此時就會觸發(fā)Seral Old收集器做兜底,會STW,整個線程不能使用)。

4.3.2、Parallel收集器(-XX:+UseParallelGC(年輕代),-XX:+UseParallelOldGC(老年代))

?????Parallel收集器其實(shí)就是Serial收集器的多線程版本,除了使用多線程進(jìn)行垃圾收集外,其余行為(控制參數(shù)、收集算法、回收策略等等)和Serial收集器類似。默認(rèn)的收集線程數(shù)跟cpu核數(shù)相同,當(dāng)然也可以用參數(shù)(XX:ParallelGCThreads)指定收集線程數(shù),但是一般不推薦修改。 Parallel Scavenge收集器關(guān)注點(diǎn)是吞吐量(高效率的利用CPU)。CMS等垃圾收集器的關(guān)注點(diǎn)更多的是用戶線程的停頓時間(提高用戶體驗)。所謂吞吐量就是CPU中用于運(yùn)行用戶代碼的時間與CPU總消耗時間的比值。
????? 新生代采用復(fù)制算法,老年代采用標(biāo)記-整理算法。
在這里插入圖片描述
?????Parallel Old收集器是Parallel Scavenge收集器的老年代版本。使用多線程和“標(biāo)記-整理”算法。在注重吞吐量以及 CPU資源的場合,都可以優(yōu)先考慮 Parallel Scavenge收集器和Parallel Old收集器(JDK8默認(rèn)的新生代和老年代收集器)。

4.3.3、ParNew收集器(-XX:+UseParNewGC)

?????ParNew收集器其實(shí)跟Parallel收集器很類似,區(qū)別主要在于它可以和CMS收集器配合使用。
?????新生代采用復(fù)制算法,老年代采用標(biāo)記-整理算法。

4.3.4、CMS收集器(-XX:+UseConcMarkSweepGC(old))

?????CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標(biāo)的收集器。它非常符合在注重用戶體驗的應(yīng)用上使用,它是HotSpot虛擬機(jī)第一款真正意義上的并發(fā)收集器,它第一次實(shí)現(xiàn)了讓垃圾收集線程與用戶線程 (基本上)同時工作。
?????從名字中的Mark Sweep這兩個詞可以看出,CMS收集器是一種 “標(biāo)記-清除”算法實(shí)現(xiàn)。
過程步驟如下:
1、初始標(biāo)記: 暫停所有的其他線程(STW),并記錄下gc roots直接能引用的對象,速度很快。
2、并發(fā)標(biāo)記: 并發(fā)標(biāo)記階段就是從GC Roots的直接關(guān)聯(lián)對象開始遍歷整個對象圖的過程, 這個過程耗時較長但是不需要停頓用戶線程, 可以與垃圾收集線程一起并發(fā)運(yùn)行。因為用戶程序繼續(xù)運(yùn)行,可能會有導(dǎo)致已經(jīng)標(biāo)記過的對象狀態(tài)發(fā)生改變。
3、重新標(biāo)記: 重新標(biāo)記階段就是為了修正并發(fā)標(biāo)記期間因為用戶程序繼續(xù)運(yùn)行而導(dǎo)致標(biāo)記產(chǎn)生變動的那一部分對象的標(biāo)記記錄,這個階段的停頓時間一般會比初始標(biāo)記階段的時間稍長,遠(yuǎn)遠(yuǎn)比并發(fā)標(biāo)記階段時間短。主要用到三色標(biāo)記里的增量更新算法(見下面詳解)做重新標(biāo)記。(也是STW)
4、并發(fā)清理: 開啟用戶線程,同時GC線程開始對未標(biāo)記的區(qū)域做清掃。這個階段如果有新增對象會被標(biāo)記為黑色不做任何處理(見下面三色標(biāo)記算法詳解)。
5、并發(fā)重置: 重置本次GC過程中的標(biāo)記數(shù)據(jù)。
在這里插入圖片描述

從它的名字就可以看出它是一款優(yōu)秀的垃圾收集器,主要優(yōu)點(diǎn):并發(fā)收集、低停頓。但是它有下面幾個明顯的缺點(diǎn):
1、對CPU資源敏感(會和服務(wù)搶資源);
2、無法處理浮動垃圾(在并發(fā)標(biāo)記和并發(fā)清理階段又產(chǎn)生垃圾,這種浮動垃圾只能等到下一次gc再清理了);
3、它使用的回收算法-“標(biāo)記-清除”算法會導(dǎo)致收集結(jié)束時會有大量空間碎片產(chǎn)生
4、執(zhí)行過程中的不確定性,會存在上一次垃圾回收還沒執(zhí)行完,然后垃圾回收又被觸發(fā)的情況,特別是在并發(fā)標(biāo)記和并發(fā)清理階段會出現(xiàn),一邊回收,系統(tǒng)一邊運(yùn)行,也許沒回收完就再次觸發(fā)full gc,也就是"concurrent mode failure",此時會進(jìn)入stop the world,用serial old垃圾收集器來回收。

4.3.5、G1收集器

???G1 (Garbage-First)是一款面向服務(wù)器的垃圾收集器,主要針對配備多顆處理器及大容量內(nèi)存的機(jī)器。以極高概率滿足GC 停頓時間要求的同時,還具備高吞吐量性能特征。
在這里插入圖片描述???G1將Java堆劃分為多個大小相等的獨(dú)立區(qū)域(Region),JVM最多可以有2048個Region。 一般Region大小等于堆大小除以2048,比如堆大小為4096M,則Region大小為2M,當(dāng)然也可以用參數(shù)"XX:G1HeapRegionSize"手動指定Region大小,但是推薦默認(rèn)的計算方式。
???G1保留了年輕代和老年代的概念,但不再是物理隔閡了,它們都是(可以不連續(xù))Region的集合。
???默認(rèn)年輕代對堆內(nèi)存的占比是5%,如果堆大小為4096M,那么年輕代占據(jù)200MB左右的內(nèi)存,對應(yīng)大概是100個 Region,可以通過“-XX:G1NewSizePercent”設(shè)置新生代初始占比,在系統(tǒng)運(yùn)行中,JVM會不停的給年輕代增加更多 的Region,但是最多新生代的占比不會超過60%,可以通過“-XX:G1MaxNewSizePercent”調(diào)整。年輕代中的Eden和 Survivor對應(yīng)的region也跟之前一樣,默認(rèn)8:1:1,假設(shè)年輕代現(xiàn)在有1000個region,eden區(qū)對應(yīng)800個,s0對應(yīng)100 個,s1對應(yīng)100個。
???一個Region可能之前是年輕代,如果Region進(jìn)行了垃圾回收,之后可能又會變成老年代,也就是說Region的區(qū)域功能 可能會動態(tài)變化。
???G1垃圾收集器對于對象什么時候會轉(zhuǎn)移到老年代跟之前講過的原則一樣,唯一不同的是對大對象的處理,G1有專門分配 大對象的Region叫Humongous區(qū),而不是讓大對象直接進(jìn)入老年代的Region中。
???在G1中,大對象的判定規(guī)則就是一個大對象超過了一個Region大小的50%,比如按照上面算的,每個Region是2M,只要一個大對象超過了1M,就會被放 入Humongous中,而且一個大對象如果太大,可能會橫跨多個Region來存放。
???Full GC的時候除了收集年輕代和老年代之外,也會將Humongous區(qū)一并回收。
G1收集器一次GC的運(yùn)作過程大致分為以下幾個步驟:
1、初始標(biāo)記(initial mark,STW): 暫停所有的其他線程,并記錄下gc roots直接能引用的對象,速度很快 ;
2、并發(fā)標(biāo)記(Concurrent Marking): 同CMS的并發(fā)標(biāo)記
3、最終標(biāo)記(Remark,STW): 同CMS的重新標(biāo)記
4、篩選回收(Cleanup,STW): 篩選回收階段首先對各個Region的回收價值和成本進(jìn)行排序,根據(jù)用戶所期望的GC停頓時間(可以用JVM參數(shù) -XX:MaxGCPauseMillis指定)來制定回收計劃,比如說老年代此時有1000個 Region都滿了,但是因為根據(jù)預(yù)期停頓時間,本次垃圾回收可能只能停頓200毫秒,那么通過之前回收成本計算得知,可能回收其中800個Region剛好需要200ms,那么就只會回收800個Region(Collection Set,要回收的集合),盡量把GC導(dǎo)致的停頓時間控制在我們指定的范圍內(nèi)。這個階段其實(shí)也可以做到與用戶程序一起并發(fā)執(zhí)行,但是因為只回收一部分Region,時間是用戶可控制的,而且停頓用戶線程將大幅提高收集效率。不管是年輕代或是老年代,回收算法主要用的是復(fù)制算法,將一個region中的存活對象復(fù)制到另一個region中,這種不會像CMS那樣 回收完因為有很多內(nèi)存碎片還需要整理一次,G1采用復(fù)制算法回收幾乎不會有太多內(nèi)存碎片。(注意:CMS回收階段是跟用戶線程一起并發(fā)執(zhí)行的,G1因為內(nèi)部實(shí)現(xiàn)太復(fù)雜暫時沒實(shí)現(xiàn)并發(fā)回收,不過到了Shenandoah就實(shí)現(xiàn)了并發(fā)收集,Shenandoah可以看成是G1的升級版本)。
在這里插入圖片描述G1收集器在后臺維護(hù)了一個優(yōu)先列表,每次根據(jù)允許的收集時間,優(yōu)先選擇回收價值大的Region(這也就是它的名字 Garbage-First的由來),比如一個Region花200ms能回收10M垃圾,另外一個Region花50ms能回收20M垃圾,在回收時間有限情況下,G1當(dāng)然會優(yōu)先選擇后面這個Region回收。這種使用Region劃分內(nèi)存空間以及有優(yōu)先級的區(qū)域回收方式,保證了G1收集器在有限時間內(nèi)可以盡可能高的收集效率。
G1垃圾收集分類:
???1、YoungGC:
???????YoungGC并不是說現(xiàn)有的Eden區(qū)放滿了就會馬上觸發(fā),G1會計算下現(xiàn)在Eden區(qū)回收大概要多久時間,如果回收時間遠(yuǎn)遠(yuǎn)小于參數(shù) -XX:MaxGCPauseMills 設(shè)定的值,那么增加年輕代的region,繼續(xù)給新對象存放,不會馬上做Young GC,直到下一次Eden區(qū)放滿,G1計算回收時間接近參數(shù) -XX:MaxGCPauseMills 設(shè)定的值,那么就會觸發(fā)Young GC。
???2、MixedGC:
???????不是FullGC,老年代的堆占有率達(dá)到參數(shù)(-XX:InitiatingHeapOccupancyPercent)設(shè)定的值則觸發(fā),回收所有的Young和部分Old(根據(jù)期望的GC停頓時間確定old區(qū)垃圾收集的優(yōu)先順序)以及大對象區(qū),正常情況G1的垃圾收集是先做MixedGC,主要使用復(fù)制算法,需要把各個region中存活的對象拷貝到別的region里去,拷貝過程中如果發(fā)現(xiàn)沒有足夠的空region能夠承載拷貝對象就會觸發(fā)一次Full GC。
???3、Full GC:
???????停止系統(tǒng)程序,然后采用單線程進(jìn)行標(biāo)記、清理和壓縮整理,好空閑出來一批Region來供下一次MixedGC使用,這 個過程是非常耗時的。(Shenandoah優(yōu)化成多線程收集了)

4.4、垃圾收集底層算法 ???????????4.4.1、三色標(biāo)記

????在并發(fā)標(biāo)記的過程中,因為標(biāo)記期間應(yīng)用線程還在繼續(xù)跑,對象間的引用可能發(fā)生變化,多標(biāo)和漏標(biāo)的情況就有可能發(fā)生。
????這里我們引入“三色標(biāo)記”來給大家解釋下,把Gc roots可達(dá)性分析遍歷對象過程中遇到的對象, 按照“是否訪問過”這個條件標(biāo)記成以下三種顏色:

  • 黑色: 表示對象已經(jīng)被垃圾收集器訪問過, 且這個對象的所有引用都已經(jīng)掃描過。 黑色的對象代表已經(jīng)掃描過, 它是安全存活的, 如果有其他對象引用指向了黑色對象,無須重新掃描一遍。 黑色對象不可能直接(不經(jīng)過灰色對象) 指向某個白色對象。
  • 灰色: 表示對象已經(jīng)被垃圾收集器訪問過, 但這個對象上至少存在一個引用還沒有被掃描過。
  • 白色: 表示對象尚未被垃圾收集器訪問過。 顯然在可達(dá)性分析剛剛開始的階段, 所有的對象都是白色的, 若 在分析結(jié)束的階段, 仍然是白色的對象, 即代表不可達(dá)。
    在這里插入圖片描述
4.5、一次完整GC流程

???這里準(zhǔn)備用大白話來給大家來講解哈。首先對象創(chuàng)建之后,會存放進(jìn)堆中新生代的Eden區(qū)中,當(dāng)Eden區(qū)滿了,會觸發(fā)minoe GC,存活的對象移動到S0區(qū),并且存活的對象GC年齡+1;此時又有新建的對象存放進(jìn)Eden區(qū),當(dāng)Eden區(qū)滿了,就又會觸發(fā)minior GC,這次不單單回收Eden區(qū),還會回收S區(qū),此時存活的對象會移動到S1區(qū),存活的對象年齡+1;反反復(fù)復(fù)這樣垃圾回收,當(dāng)對象GC年齡大于15次時,那么此時對象會存放進(jìn)老年代;當(dāng)老年代滿了之后,會觸發(fā)Full GC,F(xiàn)ull GC不單單回收老年代,它還回收新生代,F(xiàn)ull GC 的時間會比較長,大概是Minor GC的十倍左右。
???好了,上面就是一次完整的GC流程,大白話講解的應(yīng)該還算比較清晰。不理解的可以在評論中評論哦。

5、JVM調(diào)優(yōu)

???這個JVM調(diào)優(yōu)就先不給大家講解了吧,因為今天是年前上班的最后一天,已經(jīng)下班了,我還明天中午的高鐵,今天晚上回去還要收拾東西;今天就不講解了,等有時間了給大家補(bǔ)上哈。
???現(xiàn)在在回家的高鐵上,時間是2023年01月19日11:43:39,那今天作為程序員的我來裝下逼,當(dāng)然不是敲代碼哈,是來裝逼完成昨天的諾言,來兌現(xiàn)昨天說的JVM調(diào)優(yōu)這一章節(jié),廢話少說,來開始我們的寫作。
???談起JVM調(diào)優(yōu),主要的就是將其GC頻率降低和減少每次GC的時間,主要是Full GC,當(dāng)然Minor GC也是要調(diào)的,為什么是主要呢,因為Full GC時間比較長,一般是其Minor GC的十倍左右。
???調(diào)優(yōu)的主要目的是: 降低到合理的Minor GC和Full GC的頻率以及調(diào)優(yōu)到我們能夠接受的GC所用時間范圍,下面我先圍繞下面幾個大的方向來說其調(diào)優(yōu)。
???1、Minor GC方面:
???????a: 在高壓力情況下,對象創(chuàng)建的非常頻繁,那么觸發(fā)Minor GC就比較頻繁,可能有些對象根本不是大對象,但是由于頻繁觸發(fā)Minor GC,那么年齡已經(jīng)到達(dá)了15次,那么此時就會存放到老年代中,占用老年代空間就會頻繁觸發(fā)Full GC,那么這種會影響其系統(tǒng)正常使用;這種情況可以調(diào)大新生代內(nèi)存空間大小,但是調(diào)大可能內(nèi)存空間大小會增加Minor GC時間,這種帶來的GC時間延長也要能接受哈;注意: 剛剛我說的是可能增加,為什么可能增加呢,是因為新生代采用的復(fù)制算法,它的過程是先標(biāo)記,然后再復(fù)制,在這兩步中,標(biāo)記比較耗時間,復(fù)制是比較快的;但是對象存活時間比較短,可能在標(biāo)記階段就已經(jīng)是垃圾對象了,雖然的新生代空間大了,但是當(dāng)觸發(fā)Minor GC時,已經(jīng)有很多對象死亡了,無需標(biāo)記,因此我在上面說可能Minor GC的時間增大,但是不一定增大。
???????b: 當(dāng)觸發(fā)Minor GC時,存活的對象內(nèi)存可能會大于S區(qū)內(nèi)存,那么此時就會直接將對象存放進(jìn)老年代中,這種其實(shí)是非??膳碌?,因為真實(shí)該對象的GC年齡才1歲,就直接存放進(jìn)大對象中,那么Full GC會非常頻繁的。這種可以調(diào)整其Eden區(qū)和S區(qū)比例,增加其S區(qū)大小。
???????c: 還有種情況就是對象的動態(tài)年齡判斷機(jī)制,當(dāng)對象的某一年齡的內(nèi)存大小大于S區(qū)的50%,那么就會將大于等于該年齡的對象都移至老年代中,這種也會頻繁觸發(fā)Full GC,同樣解決方法是增大S區(qū)大小。

???2、大對象方面: 大對象方面其實(shí)比較好理解,上面我已經(jīng)提到了當(dāng)對象大于我們設(shè)置的-XX: PretenureSizeThreshold參數(shù)的大小時,則會認(rèn)為是大對象,會直接將對象存放進(jìn)老年代中,那么老年代的內(nèi)存空間將會很快沾滿,觸發(fā)Full GC,F(xiàn)ull GC的頻率會非常頻繁;其實(shí)這可以有兩種解決方法:
???????a: 第一種方法就是調(diào)高-XX: PretenureSizeThreshold的參數(shù)大小,使認(rèn)為不是大對象,不直接存放進(jìn)老年代中,減少Full GC的頻率,提高用戶的體驗度,但是調(diào)大其-XX: PretenureSizeThreshold的參數(shù)大小后,要注意S區(qū)的大小,如果S區(qū)的內(nèi)存不足以存放,又觸發(fā)了上述的動態(tài)年齡判斷和大于S區(qū)內(nèi)存的50%,又給直接存放進(jìn)了老年代,那么這種情況是不行的,因此也要注意下這種問題。
???????b: 我們也可以編寫個腳本,在系統(tǒng)不忙的情況下運(yùn)行該腳本去進(jìn)行Full GC;這種情況是不提倡的哈,盡量還是采用上面的a方法。
???3、內(nèi)存泄漏引起的頻繁Minor GC和Full GC: 最終會引發(fā)OOM,因此在編寫代碼的時候一定要注意。
???4、純代碼方面: 這里可能是某些for循環(huán)創(chuàng)建大量對象和使用了不當(dāng)?shù)臄?shù)據(jù)結(jié)構(gòu)能問題引起的頻繁GC,針對這種情況就建議查看代碼來進(jìn)行解決了。
???好了上面就是大致的調(diào)優(yōu)方面的建議,具體的調(diào)優(yōu)過程就不給大家分享了,這方面的調(diào)優(yōu)只能實(shí)戰(zhàn)才能悟出來真理,我如果直接給你講解的話也不太好,還希望大家實(shí)戰(zhàn)吧。
???好了經(jīng)過四十分鐘在高鐵上的寫終于寫完了,也裝逼完了,好了,今天2023年01月19日12:25:38這篇文章暫時 分享到這吧,等后期有需要補(bǔ)充的再補(bǔ)充?!贕8270高鐵

???
???廢話少說,趕緊來個結(jié)尾,準(zhǔn)備收拾東西下班回家過年!
???再次提前祝大家新年快樂哦(從下寫作文老師就教導(dǎo)我們寫作文要首尾相應(yīng)🐶)
???文章中有講解不對的內(nèi)容希望大家在評論區(qū)中指出哦,希望大家點(diǎn)贊評論轉(zhuǎn)發(fā)哦,點(diǎn)贊超過三個我就更新下一篇——MySQL系列

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

新聞標(biāo)題:2023跳槽最新面試題整理——JVM系列-創(chuàng)新互聯(lián)
鏈接URL:http://aaarwkj.com/article16/ccdidg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、小程序開發(fā)標(biāo)簽優(yōu)化、移動網(wǎng)站建設(shè)企業(yè)網(wǎng)站制作、靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化
久热在线这里只有精品| 午夜国产精品福利一二| 亚洲综合日韩丝袜人妻| 日韩亚洲在线中文字幕| 亚洲一区二区三区熟女少妇| 91这里只有精品在线观看| 很黄无遮挡在线免费网站| 亚洲不卡免费在线视频| 国产亚洲一区二区三区av| 国产亚洲欧美精品久久久久| 一区二区蜜桃在线观看 | 哪里可以看黄色片日韩| 欧美人妻不卡一区二区久久| 中文字幕国产精品91| 亚洲热久久国产经典视频| 亚洲视频一直看一直爽| av国产一区二区在线| 中文字幕人成乱码在线观看| 禁止18观看视频软件| 亚洲另类熟女国产精品老| 亚洲综合日韩精品在线| 成人黄色动漫在线播放| 四虎在线免费视频播放| 成人av免费高清在线| 日本九州不卡久久精品一区| 国产精品日本一区二区| 美女一区二区三区日本美女在线观看| 丰满人妻侵犯中文字幕| 免费看的日韩av毛片| 99热在线播放精品观看| 欧美午夜激情片在线观看| 日本道欧美一区二区aaaa| 国产一区二区三区av在线播放| 亚洲天堂日韩欧美在线| 久久亚洲欧洲日本韩国欧美| 久久国产精品99亚洲| 亚洲永久免费精品一区二区三区| 黄色三级亚洲男人的天堂| 日本一本一道高清不卡视频| 97水蜜桃视频在线观看| 黑人巨大欧美一区二区|