最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
面試官,不要再問(wèn)我“JavaGC垃圾回收機(jī)制”了

推薦閱讀:我憑借這份pdf拿下了螞蟻金服、字節(jié)跳動(dòng)、小米等大廠的offer

Java GC垃圾回收幾乎是面試必問(wèn)的JVM問(wèn)題之一,本篇文章帶領(lǐng)大家了解Java GC的底層原理,圖文并茂,突破學(xué)習(xí)及面試瓶頸。

創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司提供網(wǎng)站設(shè)計(jì)和自適應(yīng)建站服務(wù)。團(tuán)隊(duì)由有經(jīng)驗(yàn)的網(wǎng)頁(yè)設(shè)計(jì)師、程序員和市場(chǎng)專(zhuān)家組成,能夠提供從H5技術(shù),網(wǎng)站制作,廣告投放平臺(tái),模板建站到微信平臺(tái)小程序開(kāi)發(fā)等全方位服務(wù)。 以客戶為中心,致力于為客戶提供創(chuàng)新、高效的解決方案,幫助您打造成功的企業(yè)網(wǎng)站。

楔子-JVM內(nèi)存結(jié)構(gòu)補(bǔ)充

JVM中堆的結(jié)構(gòu)圖

面試官,不要再問(wèn)我“Java GC垃圾回收機(jī)制”了

圖中展示了堆中三個(gè)區(qū)域:Eden、From Survivor、To Survivor。從圖中可以也可以看到它們的大小比例,準(zhǔn)確來(lái)說(shuō)是:8:1:1。為什么要這樣設(shè)計(jì)呢,本篇文章后續(xù)會(huì)給出解答,還是根據(jù)垃圾回收的具體情況來(lái)設(shè)計(jì)的。

還記得在設(shè)置JVM時(shí),常用的類(lèi)似-Xms和-Xmx等參數(shù)嗎?對(duì)的它們就是用來(lái)說(shuō)設(shè)置堆中各區(qū)域的大小的。

面試官,不要再問(wèn)我“Java GC垃圾回收機(jī)制”了

控制參數(shù)詳解:

  • -Xms設(shè)置堆的最小空間大小。
  • -Xmx設(shè)置堆的最大空間大小。
  • -Xmn堆中新生代初始及最大大?。∟ewSize和MaxNewSize為其細(xì)化)。
  • -XX:NewSize設(shè)置新生代最小空間大小。
  • -XX:MaxNewSize設(shè)置新生代最大空間大小。
  • -XX:PermSize設(shè)置永久代最小空間大小。
  • -XX:MaxPermSize設(shè)置永久代最大空間大小。
  • -Xss設(shè)置每個(gè)線程的堆棧大小。

對(duì)照上面兩個(gè)圖,再來(lái)看這些參數(shù)是不是沒(méi)有之前那么枯燥了,它們?cè)趫D中都有了對(duì)應(yīng)的位置。

有沒(méi)有發(fā)現(xiàn)沒(méi)有直接設(shè)置老年代空間大小的參數(shù)?我們通過(guò)簡(jiǎn)單的計(jì)算獲得。

老年代空間大小=堆空間大小-年輕代大空間大小

對(duì)上面參數(shù)立即了,但記憶有困難?那么,以下幾個(gè)助記詞可能更好的幫你記憶和理解參數(shù)的含義。

Xmx(memory maximum), Xms(memory startup), Xmn(memory nursery/new), Xss(stack size)。

對(duì)于參數(shù)的格式可以這樣理解:

  • -: 標(biāo)準(zhǔn)VM選項(xiàng),VM規(guī)范的選項(xiàng)。
  • -X: 非標(biāo)準(zhǔn)VM選項(xiàng),不保證所有VM支持。
  • -XX: 高級(jí)選項(xiàng),高級(jí)特性,但屬于不穩(wěn)定的選項(xiàng)。

GC概述

垃圾收集(Garbage Collection)通常被稱(chēng)為“GC”,由虛擬機(jī)“自動(dòng)化”完成垃圾回收工作。

思考一個(gè)問(wèn)題,既然GC會(huì)自動(dòng)回收,開(kāi)發(fā)人員為什么要學(xué)習(xí)GC和內(nèi)存分配呢?為了能夠配置上面的參數(shù)配置?參數(shù)配置又是為了什么?

當(dāng)需要排查各種內(nèi)存溢出,內(nèi)存泄露問(wèn)題時(shí),當(dāng)垃圾成為系統(tǒng)達(dá)到更高并發(fā)量的瓶頸時(shí),我們就需要對(duì)GC的自動(dòng)回收實(shí)施必要的監(jiān)控和調(diào)節(jié)。

JVM中程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧3個(gè)區(qū)域隨線程而生隨線程而滅。棧幀隨著方法的進(jìn)入和退出做入棧和出棧操作,實(shí)現(xiàn)了自動(dòng)的內(nèi)存清理。它們的內(nèi)存分配和回收都具有確定性。

因此,GC垃圾回收主要集中在堆和方法區(qū),在程序運(yùn)行期間,這部分內(nèi)存的分配和使用都是動(dòng)態(tài)的。

下面通過(guò)概念和具體的算法來(lái)了解GC垃圾回收的過(guò)程。

如何判斷對(duì)象存活

判斷對(duì)象常規(guī)有兩種方法:引用計(jì)數(shù)算法和可達(dá)性分析算法(Reachability Analysis)。

引用計(jì)數(shù)算法:給對(duì)象添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用它時(shí)計(jì)數(shù)器加1,引用釋放時(shí)計(jì)數(shù)減1,當(dāng)計(jì)數(shù)器為0時(shí)可以回收。

引用計(jì)數(shù)算法實(shí)現(xiàn)簡(jiǎn)單,判斷高效,在微軟COM和Python語(yǔ)言等被廣泛使用,但在主流的Java虛擬機(jī)中沒(méi)有使用該方法,主要是因?yàn)闊o(wú)法解決對(duì)象相互循環(huán)引用的問(wèn)題。

可達(dá)性分析算法:基本思想是通過(guò)一系列稱(chēng)為“GC Root”的對(duì)象(如系統(tǒng)類(lèi)加載器、棧中的對(duì)象、處于激活狀態(tài)的線程等)作為起點(diǎn),基于對(duì)象引用關(guān)系,開(kāi)始向下搜索,所走過(guò)的路徑稱(chēng)為引用鏈,當(dāng)一個(gè)對(duì)象到GC Root沒(méi)有任何引用鏈相連,證明對(duì)象是不可用的。

面試官,不要再問(wèn)我“Java GC垃圾回收機(jī)制”了

上圖中中綠色部分為存活對(duì)象,灰色部分為可回收對(duì)象。雖然灰色部分內(nèi)部依舊有關(guān)聯(lián),但它們到GC Root是不可達(dá)的。

面試問(wèn)題

面試官,說(shuō)說(shuō)Java GC都用了哪些算法?分別應(yīng)用在什么地方?

答:復(fù)制算法、標(biāo)記清除、標(biāo)記整理……

你還在單純的死記硬背么?繼續(xù)往下看,你會(huì)豁然開(kāi)朗,再也不用死記硬背了。

標(biāo)記清除算法

標(biāo)記清除(Mark-Sweep)算法,包含“標(biāo)記”和“清除”兩個(gè)階段:首先標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收掉所有被標(biāo)記的對(duì)象。

標(biāo)記清除算法是最基礎(chǔ)的收集算法,后續(xù)的收集算法都是基于該思路并對(duì)其缺點(diǎn)進(jìn)行改進(jìn)而得到的。

面試官,不要再問(wèn)我“Java GC垃圾回收機(jī)制”了

主要缺點(diǎn):一個(gè)是效率問(wèn)題,標(biāo)記和清除過(guò)程的效率都不高;另外是空間問(wèn)題,標(biāo)記清除之后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會(huì)導(dǎo)致,當(dāng)程序在以后的運(yùn)行過(guò)程中需要分配較大對(duì)象時(shí)無(wú)法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動(dòng)作。

復(fù)制算法

復(fù)制(Copying)算法:將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當(dāng)一塊內(nèi)存用完了,就將還存活著的對(duì)象復(fù)制到另外一塊上,然后清理掉前一塊。

面試官,不要再問(wèn)我“Java GC垃圾回收機(jī)制”了

每次對(duì)半?yún)^(qū)內(nèi)存回收時(shí)、內(nèi)存分配時(shí)就不用考慮內(nèi)存碎片等復(fù)雜情況,只要移動(dòng)堆頂指針,按順序分配內(nèi)存即可,實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效。

缺點(diǎn):將內(nèi)存縮小為一半,性價(jià)比低,持續(xù)復(fù)制長(zhǎng)生存期的對(duì)象則導(dǎo)致效率低下。

JVM堆中新生代便采用復(fù)制算法?;氐阶畛跬品峙浣Y(jié)構(gòu)圖。

面試官,不要再問(wèn)我“Java GC垃圾回收機(jī)制”了

在GC回收過(guò)程中,當(dāng)Eden區(qū)滿時(shí),還存活的對(duì)象會(huì)被復(fù)制到其中一個(gè)Survivor區(qū);當(dāng)回收時(shí),會(huì)將Eden和使用的Survivor區(qū)還存活的對(duì)象,復(fù)制到另外一個(gè)Survivor區(qū),然后對(duì)Eden和用過(guò)的Survivor區(qū)進(jìn)行清理。

如果另外一個(gè)Survivor區(qū)沒(méi)有足夠的內(nèi)存存儲(chǔ)時(shí),則會(huì)進(jìn)入老年代。

這里針對(duì)哪些對(duì)象會(huì)進(jìn)入老年代有這樣的機(jī)制:對(duì)象每經(jīng)歷一次復(fù)制,年齡加1,達(dá)到晉升年齡閾值后,轉(zhuǎn)移到老年代。

在這整個(gè)過(guò)程中,由于Eden中的對(duì)象屬于像浮萍一樣“瞬生瞬滅”的對(duì)象,所以并不需要1:1的比例來(lái)分配內(nèi)存,而是采用了8:1:1的比例來(lái)分配。

而針對(duì)那些像“水熊蟲(chóng)”一樣,歷經(jīng)多次清理依舊存活的對(duì)象,則會(huì)進(jìn)入老年代,而老年的清理算法則采用下面要講到的“標(biāo)記整理算法”。

標(biāo)記整理算法

標(biāo)記整理(Mark-Compact)算法:標(biāo)記過(guò)程與“標(biāo)記-清除”算法一樣,但后續(xù)步驟不是直接對(duì)可回收對(duì)象進(jìn)行清理,而是讓所有存活的對(duì)象都向一端移動(dòng),然后直接清理掉端邊界以外的內(nèi)存。

面試官,不要再問(wèn)我“Java GC垃圾回收機(jī)制”了

這種算法不既不用浪費(fèi)50%的內(nèi)存,也解決了復(fù)制算法在對(duì)象存活率較高時(shí)的效率低下問(wèn)題。

分代收集算法

分代收集算法,基本思路:將Java的堆內(nèi)存邏輯上分成兩塊,新生代和老年代,針對(duì)不同存活周期、不同大小的對(duì)象采取不同的垃圾回收策略。

而在新生代中大多數(shù)對(duì)象都是瞬間對(duì)象,只有少量對(duì)象存活,復(fù)制較少對(duì)象即可完成清理,因此采用復(fù)制算法。而針對(duì)老年代中的對(duì)象,存活率較高,又沒(méi)有額外的擔(dān)保內(nèi)存,因此采用標(biāo)記整理算法。

其實(shí),回頭看,分代收集算法就是對(duì)新生代和老年代算法從策略維度的規(guī)劃而已。

小結(jié)

至此,當(dāng)面試官再問(wèn)Java GC都用到了哪些垃圾回收算法和分別應(yīng)用在什么場(chǎng)景下的問(wèn)題,再也不用死記硬背了吧?


網(wǎng)站題目:面試官,不要再問(wèn)我“JavaGC垃圾回收機(jī)制”了
網(wǎng)頁(yè)地址:http://fisionsoft.com.cn/article/gdpcee.html