深入了解jvm回收機制

目的

主要介紹java 垃圾回收如何與hotspot JVM配合使用的基礎知識靶溜。在了解了垃圾收集器的功能后开瞭,了解Visual VM監(jiān)控垃圾收集的過程。

探索JVM架構

Hotspot 架構

HotSpot JVM 的架構支持強大的特性和能力基礎罩息,并支持實現(xiàn)高性能和大規(guī)泥拖辏可擴展性的能力。例如瓷炮,HotSpot JVM JIT 編譯器生成動態(tài)優(yōu)化葱色。換句話說,它們在 Java 應用程序運行時做出優(yōu)化決策崭别,并生成針對底層系統(tǒng)架構的高性能本機機器指令冬筒。此外恐锣,通過其運行時環(huán)境和多線程垃圾收集器的成熟演變和持續(xù)工程茅主,HotSpot JVM 即使在最大的可用計算機系統(tǒng)上也能產(chǎn)生高可擴展性。


Hotspot 架構

關鍵組件

在調(diào)整性能時土榴,JVM 有三個組件是重點诀姚。堆是存儲對象數(shù)據(jù)的位置。然后玷禽,此區(qū)域由啟動時選擇的垃圾回收器管理赫段。大多數(shù)優(yōu)化選項都與調(diào)整堆大小和根據(jù)您的情況選擇最合適的垃圾回收器有關。JIT 編譯器對性能也有很大的影響矢赁,但很少需要使用較新版本的 JVM 進行調(diào)優(yōu)糯笙。


Key Hotspot Components

垃圾回收

什么是自動垃圾回收?

自動垃圾回收是查看堆內(nèi)存撩银、識別哪些對象正在使用以及哪些對象未使用以及刪除未使用對象的過程给涕。正在使用的對象或引用的對象意味著程序的某些部分仍保留指向該對象的指針。未使用的對象或未引用的對象不再被程序的任何部分引用。因此够庙,可以回收未引用對象使用的內(nèi)存恭应。

在像C這樣的編程語言中,分配和釋放內(nèi)存是一個手動過程耘眨。在 Java 中昼榛,釋放內(nèi)存的過程由垃圾回收器自動處理√弈眩基本過程分為以下幾步:

1. 標記

標記的作用是垃圾回收器識別哪些內(nèi)存正在使用和哪些未使用胆屿。
引用的對象以藍色顯示;未引用的對象以金黃色顯示偶宫。
在標記階段莺掠,所有對象將被掃描,并被標記读宙。如果必須掃描系統(tǒng)中的所有對象彻秆,這可能是一個非常耗時的過程。


標記

2. 正常刪除

正常刪除會刪除未引用的對象结闸,留下引用的對象和指向可用空間的指針唇兑。
內(nèi)存分配器保存對可用空間塊的引用,可以在其中分配新對象桦锄。


正常刪除

使用壓縮進行刪除

若要進一步提高性能扎附,除了刪除未引用的對象外,還可以壓縮其余引用的對象结耀。通過將引用的對象移動到一起留夜,這使得新的內(nèi)存分配更加容易和快捷。


壓縮刪除

為什么要進行按“代”進行垃圾回收图甜?

通過前面的描述碍粥,我們可以了解到標記和壓縮jvm中所有的對象是低效的、耗時的黑毅。隨著分配的對象越來越多嚼摩,對象的列表會越來越長,從而導致垃圾回收的時間越來越長矿瘦。然而通過對應用程序的實際分析發(fā)現(xiàn)枕面,大部分對象的使用時間都是短暫的。
下面是此類數(shù)據(jù)的示例缚去,Y 軸顯示分配的字節(jié)數(shù)潮秘,X 訪問顯示隨時間分配的字節(jié)數(shù)。


image.png

如您縮減易结,隨著時間的推移枕荞,保留分配的對象越來越少稠通。所以實際上,大多數(shù)的對象壽命非常短买猖,正如圖左側的較高值所示改橘。

JVM年齡代

JVM代分布

堆空間包括:年輕代、年老代玉控、永生代飞主。
年輕代(eden) 是分配和老化所有新生對象的地方。當年輕代被填滿時高诺,會導致小的垃圾回收碌识。
S0S1是兩個大小相同的內(nèi)存區(qū)域虱而,主要存放每次垃圾回收后eden區(qū)存活的對象筏餐,作為對象從eden過渡到年老代的緩沖地帶。
年老代主要存放生命周期長的存活對象牡拇。通常為年輕代設置閾值魁瞪,當達到該年齡后,對象將被移動到年老代惠呼。
永生代 主要存放所有已加載的類信息导俘、方法信息、常量池等剔蹋÷帽。可通過-XX:PermSize和-XX:MaxPermSize來指定持久帶初始化值和最大值。Permanent Space并不等同于方法區(qū)泣崩,只不過是Hotspot JVM用Permanent Space來實現(xiàn)方法區(qū)而已少梁,有些虛擬機沒有Permanent Space而用其他機制來實現(xiàn)方法區(qū)。

對象分配和老化的過程

  1. 任何新對象都會被分配到eden區(qū)矫付,S0凯沪、S1開始都是空的


    image.png
  2. 當eden區(qū)被填滿時,將會觸發(fā)一次小的垃圾回收


    image.png
  3. 此時被引用的對象將會被移動到S0技即,未被引用的對象將被刪除


    image.png
  4. 在下一次的Minor GC中著洼,Eden區(qū)的情況和上面一致,沒有引用的對象被回收而叼,存活的對象被復制到survivor區(qū)。然而在survivor區(qū)豹悬,S0的所有的數(shù)據(jù)都被復制到S1葵陵,需要注意的是,在上次minor GC過程中移動到S0中的兩個對象在復制到S1后其年齡要加1瞻佛。此時Eden區(qū)S0區(qū)被清空脱篙,所有存活的數(shù)據(jù)都復制到了S1區(qū)娇钱,并且S1區(qū)存在著年齡不一樣的對象


    image.png
  5. 再下一次Minor GC則重復這個過程,這一次survivor的兩個區(qū)對換绊困,存活的對象被復制到S0文搂,存活的對象年齡加1,Eden區(qū)和另一個survivor區(qū)被清空秤朗。


    image.png
  6. 下面演示一下Promotion過程煤蹭,再經(jīng)過幾次Minor GC之后,當存活對象的年齡達到一個閾值之后(可通過參數(shù)配置取视,默認是8)硝皂,就會被從年輕代Promotion到老年代。


    image.png
  7. 隨著Minor GC一次又一次的進行作谭,不斷會有新的對象被promote到老年代稽物。
    隨著MinorGC一次又一次的進行,不斷會有新的對象被promote到老年代折欠。

  8. 上面基本上覆蓋了整個年輕代所有的回收過程贝或。最終,Major GC將會在老年代發(fā)生锐秦,老年代的空間將會被清除和壓縮傀缩。


    image.png

總結

從上面的過程可以看出,Eden區(qū)是連續(xù)的空間农猬,且Survivor總有一個為空赡艰。經(jīng)過一次GC和復制,一個Survivor中保存著當前還活著的對象斤葱,而Eden區(qū)和另一個Survivor區(qū)的內(nèi)容都不再需要了慷垮,可以直接清空,到下一次GC時揍堕,兩個Survivor的角色再互換料身。因此,這種方式分配內(nèi)存和清理內(nèi)存的效率都極高衩茸,這種垃圾回收的方式就是著名的“停止-復制(Stop-and-copy)”清理法(將Eden區(qū)和一個Survivor中仍然存活的對象拷貝到另一個Survivor中)芹血,這不代表著停止復制清理法很高效,其實楞慈,它也只在這種情況下(基于大部分對象存活周期很短的事實)高效幔烛,如果在老年代采用停止復制,則是非常不合適的囊蓝。老年代存儲的對象比年輕代多得多饿悬,而且不乏大對象,對老年代進行內(nèi)存清理時聚霜,如果使用停止-復制算法狡恬,則相當?shù)托е槭濉R话悖夏甏玫乃惴ㄊ菢擞?壓縮算法弟劲,即:標記出仍然存活的對象(存在引用的)祷安,將所有存活的對象向一端移動,以保證內(nèi)存的連續(xù)兔乞。在發(fā)生Minor GC時汇鞭,虛擬機會檢查每次晉升進入老年代的大小是否大于老年代的剩余空間大小,如果大于报嵌,則直接觸發(fā)一次Full GC虱咧,否則,就查看是否設置了-XX:+HandlePromotionFailure(允許擔保失斆)腕巡,如果允許,則只會進行MinorGC血筑,此時可以容忍內(nèi)存分配失敾娉痢;如果不允許豺总,則仍然進行Full GC(這代表著如果設置-XX:+Handle PromotionFailure车伞,則觸發(fā)MinorGC就會同時觸發(fā)Full GC,哪怕老年代還有很多內(nèi)存喻喳,所以另玖,最好不要這樣做)。
關于方法區(qū)(共享內(nèi)存區(qū)的持久代)即永久代的回收表伦,永久代的回收有兩種:常量池中的常量谦去,無用的類信息,常量的回收很簡單蹦哼,沒有引用了就可以被回收鳄哭。對于無用的類進行回收,必須保證3點:

  • 類的所有實例都已經(jīng)被回收
  • 加載類的ClassLoader已經(jīng)被回收
  • 類對象的Class對象沒有被引用(即沒有通過反射引用該類的地方)

永久代的回收并不是必須的纲熏,可以通過參數(shù)來設置是否對類進行回收妆丘。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市局劲,隨后出現(xiàn)的幾起案子勺拣,更是在濱河造成了極大的恐慌,老刑警劉巖容握,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宣脉,死亡現(xiàn)場離奇詭異,居然都是意外死亡剔氏,警方通過查閱死者的電腦和手機塑猖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谈跛,“玉大人羊苟,你說我怎么就攤上這事「泻叮” “怎么了蜡励?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長阻桅。 經(jīng)常有香客問我凉倚,道長,這世上最難降的妖魔是什么嫂沉? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任稽寒,我火速辦了婚禮,結果婚禮上趟章,老公的妹妹穿的比我還像新娘杏糙。我一直安慰自己,他們只是感情好蚓土,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布宏侍。 她就那樣靜靜地躺著,像睡著了一般蜀漆。 火紅的嫁衣襯著肌膚如雪谅河。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天确丢,我揣著相機與錄音绷耍,去河邊找鬼。 笑死蠕嫁,一個胖子當著我的面吹牛锨天,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剃毒,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼病袄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了赘阀?” 一聲冷哼從身側響起益缠,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎基公,沒想到半個月后幅慌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡轰豆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年胰伍,在試婚紗的時候發(fā)現(xiàn)自己被綠了齿诞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡骂租,死狀恐怖祷杈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情渗饮,我是刑警寧澤但汞,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站互站,受9級特大地震影響私蕾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胡桃,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一踩叭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧标捺,春花似錦懊纳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至闺兢,卻和暖如春茂缚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背屋谭。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工脚囊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人桐磁。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓悔耘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親我擂。 傳聞我的和親對象是個殘疾皇子衬以,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

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