圖解:Java垃圾回收機(jī)制,在看不會(huì)去跪搓衣板吧

什么是自動(dòng)垃圾回收主之?

自動(dòng)垃圾回收是一種在堆內(nèi)存中找出哪些對(duì)象在被使用择吊,還有哪些對(duì)象沒(méi)被使用,并且將后者刪掉的機(jī)制槽奕。

所謂使用中的對(duì)象(已引用對(duì)象)几睛,指的是程序中有指針指向的對(duì)象;而未使用中的對(duì)象(未引用對(duì)象)粤攒,則沒(méi)有被任何指針給指向所森,因此占用的內(nèi)存也可以被回收掉。

在用 C 之類(lèi)的編程語(yǔ)言時(shí)夯接,程序員需要自己手動(dòng)分配和釋放內(nèi)存焕济。而 Java 不一樣,它有垃圾回收器盔几,釋放內(nèi)存由回收器負(fù)責(zé)晴弃。本文接下來(lái)將介紹垃圾回收機(jī)制的基本過(guò)程。

第一步:標(biāo)記

垃圾回收的第一步是標(biāo)記逊拍。垃圾回收器此時(shí)會(huì)找出哪些內(nèi)存在使用中上鞠,還有哪些不是。

上圖中芯丧,藍(lán)色表示已引用對(duì)象芍阎,橙色表示未引用對(duì)象。垃圾回收器要檢查完所有的對(duì)象缨恒,才能知道哪些有被引用谴咸,哪些沒(méi)度硝。如果系統(tǒng)里所有的對(duì)象都要檢查,那這一步可能會(huì)相當(dāng)耗時(shí)間寿冕。

第二步:清除

這一步會(huì)刪掉標(biāo)記出的未引用對(duì)象。

內(nèi)存分配器會(huì)保留指向可用內(nèi)存的引用椒袍,以供分配新對(duì)象驼唱。

壓縮

為了提升性能,刪除了未引用對(duì)象后驹暑,還可以將剩下的已引用對(duì)象放在一起(壓縮)玫恳,這樣就能更簡(jiǎn)單快捷地分配新對(duì)象了。

為什么需要分代垃圾收集优俘?

之前說(shuō)過(guò)京办,逐一標(biāo)記和壓縮 Java 虛擬機(jī)里的所有對(duì)象非常低效:分配的對(duì)象越多,垃圾回收需時(shí)就越久帆焕。不過(guò)惭婿,根據(jù)統(tǒng)計(jì),大部分的對(duì)象叶雹,其實(shí)用沒(méi)多久就不用了财饥。

來(lái)看個(gè)例子吧。(下圖中折晦,豎軸代表已分配的字節(jié)钥星,而橫軸代表程序運(yùn)行時(shí)間)

上圖可見(jiàn),存活(沒(méi)被釋放)的對(duì)象隨運(yùn)行時(shí)間越來(lái)越少满着。而圖中左側(cè)的那些峰值谦炒,也表明了大部分對(duì)象其實(shí)都挺短命的。

JVM 分代

根據(jù)之前的規(guī)律风喇,就可以用來(lái)提升 JVM 的效率了宁改。方法是,把堆分成幾個(gè)部分(就是所謂的分代)响驴,分別是新生代透且、老年代,以及永生代豁鲤。

新對(duì)象會(huì)被分配在新生代內(nèi)存秽誊。一旦新生代內(nèi)存滿(mǎn)了,就會(huì)開(kāi)始對(duì)死掉的對(duì)象琳骡,進(jìn)行所謂的小型垃圾回收過(guò)程锅论。一片新生代內(nèi)存里,死掉的越多楣号,回收過(guò)程就越快最易;至于那些還活著的對(duì)象怒坯,此時(shí)就會(huì)老化,并最終老到進(jìn)入老年代內(nèi)存藻懒。

Stop the World 事件?—— 小型垃圾回收屬于一種叫?"Stop the World" 的事件剔猿。在這種事件發(fā)生時(shí),所有的程序線(xiàn)程都要暫停嬉荆,直到事件完成(比如這里就是完成了所有回收工作)為止归敬。

老年代用來(lái)保存長(zhǎng)時(shí)間存活的對(duì)象。通常鄙早,設(shè)置一個(gè)閾值汪茧,當(dāng)達(dá)到該年齡時(shí),年輕代對(duì)象會(huì)被移動(dòng)到老年代限番。最終老年代也會(huì)被回收舱污。這個(gè)事件成為 Major GC。

Major GC 也會(huì)觸發(fā)STW(Stop the World)弥虐。通常扩灯,Major GC會(huì)慢很多,因?yàn)樗婕暗剿写婊顚?duì)象躯舔。所以驴剔,對(duì)于響應(yīng)性的應(yīng)用程序,應(yīng)該盡量避免Major GC粥庄。還要注意丧失,Major GC的STW的時(shí)長(zhǎng)受年老代垃圾回收器類(lèi)型的影響。

永久代包含JVM用于描述應(yīng)用程序中類(lèi)和方法的元數(shù)據(jù)惜互。永久代是由JVM在運(yùn)行時(shí)根據(jù)應(yīng)用程序使用的類(lèi)來(lái)填充的布讹。此外,Java SE類(lèi)庫(kù)和方法也存儲(chǔ)在這里训堆。

如果JVM發(fā)現(xiàn)某些類(lèi)不再需要描验,并且其他類(lèi)可能需要空間,則這些類(lèi)可能會(huì)被回收坑鱼。

世代垃圾收集過(guò)程

現(xiàn)在你已經(jīng)理解了為什么堆被分成不同的代膘流,現(xiàn)在是時(shí)候看看這些空間是如何相互作用的。后面的圖片將介紹JVM中的對(duì)象分配和老化過(guò)程鲁沥。關(guān)注微信公眾號(hào)呼股,,一份超全 JVM 調(diào)優(yōu)攻略画恰。

首先彭谁,將任何新對(duì)象分配給 eden 空間。兩個(gè) survivor 空間都是空的允扇。

當(dāng) eden 空間填滿(mǎn)時(shí)缠局,會(huì)觸發(fā)輕微的垃圾收集则奥。

引用的對(duì)象被移動(dòng)到第一個(gè) survivor 空間。清除 eden 空間時(shí)狭园,將刪除未引用的對(duì)象读处。

在下一次Minor GC中,Eden區(qū)也會(huì)做同樣的操作唱矛。刪除未被引用的對(duì)象档泽,并將被引用的對(duì)象移動(dòng)到Survivor區(qū)。然而揖赴,這里,他們被移動(dòng)到了第二個(gè)Survivor區(qū)(S1)抑胎。

此外燥滑,第一個(gè)Survivor區(qū)(S0)中,在上一次Minor GC幸存的對(duì)象阿逃,會(huì)增加年齡铭拧,并被移動(dòng)到S1中。待所有幸存對(duì)象都被移動(dòng)到S1后恃锉,S0和Eden區(qū)都會(huì)被清空搀菩。注意,Survivor區(qū)中有了不同年齡的對(duì)象破托。

在下一次Minor GC中肪跋,會(huì)重復(fù)同樣的操作。不過(guò)土砂,這一次Survivor區(qū)會(huì)交換州既。被引用的對(duì)象移動(dòng)到S0,。幸存的對(duì)象增加年齡萝映。Eden區(qū)和S1被清空吴叶。

?此幻燈片演示了 promotion。在較小的GC之后序臂,當(dāng)老化的物體達(dá)到一定的年齡閾值(在該示例中為8)時(shí)蚌卤,它們從年輕一代晉升到老一代。

隨著較小的GC持續(xù)發(fā)生奥秆,物體將繼續(xù)被推廣到老一代空間逊彭。

所以這幾乎涵蓋了年輕一代的整個(gè)過(guò)程。最終吭练,將主要對(duì)老一代進(jìn)行GC诫龙,清理并最終壓縮該空間。

根據(jù)多年架構(gòu)經(jīng)驗(yàn)鲫咽,整理了一批Java架構(gòu)學(xué)習(xí)資料(里面包含有Java工程化签赃、高性能及分布式谷异、高性能、深入淺出锦聊。高架構(gòu)歹嘹。性能調(diào)優(yōu)、Spring孔庭,MyBatis尺上,Netty源碼分析和大數(shù)據(jù)等多個(gè)知識(shí)點(diǎn)的架構(gòu)資料)合理利用自己每一分每一秒的時(shí)間來(lái)學(xué)習(xí)提升自己,不要再用"沒(méi)有時(shí)間“來(lái)掩飾自己思想上的懶惰圆到!趁年輕怎抛,使勁拼,給未來(lái)的自己一個(gè)交代芽淡!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末马绝,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子挣菲,更是在濱河造成了極大的恐慌富稻,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件白胀,死亡現(xiàn)場(chǎng)離奇詭異椭赋,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)或杠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)哪怔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人向抢,你說(shuō)我怎么就攤上這事蔓涧。” “怎么了笋额?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵元暴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我兄猩,道長(zhǎng)茉盏,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任枢冤,我火速辦了婚禮鸠姨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘淹真。我一直安慰自己讶迁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布核蘸。 她就那樣靜靜地躺著巍糯,像睡著了一般啸驯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上祟峦,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天罚斗,我揣著相機(jī)與錄音,去河邊找鬼宅楞。 笑死针姿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的厌衙。 我是一名探鬼主播距淫,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼婶希!你這毒婦竟也來(lái)了溉愁?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饲趋,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后撤蟆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體奕塑,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年家肯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了龄砰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡讨衣,死狀恐怖换棚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情反镇,我是刑警寧澤固蚤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站歹茶,受9級(jí)特大地震影響夕玩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惊豺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一燎孟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尸昧,春花似錦揩页、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)萍程。三九已至,卻和暖如春累提,著一層夾襖步出監(jiān)牢的瞬間尘喝,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工斋陪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朽褪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓无虚,卻偏偏與公主長(zhǎng)得像缔赠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子友题,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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