Java垃圾回收機制你還不明白?一線大廠面試必問的!

什麼是自動垃圾回收?程序員

自動垃圾回收是一種在堆內存中找出哪些對象在被使用,還有哪些對象沒被使用,而且將後者刪掉的機制。編程

所謂使用中的對象(已引用對象),指的是程序中有指針指向的對象;而未使用中的對象(未引用對象),則沒有被任何指針給指向,所以佔用的內存也能夠被回收掉。app

在用 C 之類的編程語言時,程序員須要本身手動分配和釋放內存。而 Java 不同,它有垃圾回收器,釋放內存由回收器負責。本文接下來將介紹垃圾回收機制的基本過程。編程語言

v2-21b09b7c87782492960fbb156e714db1_hd.png

標記ide

垃圾回收的第一步是標記。垃圾回收器此時會找出哪些內存在使用中,還有哪些不是。性能

v2-561732a6a667a6000b8c18be28f85dec_hd.jpg

上圖中,藍色表示已引用對象,橙色表示未引用對象。垃圾回收器要檢查完全部的對象,才能知道哪些有被引用,哪些沒。若是系統裏全部的對象都要檢查,那這一步可能會至關耗時間。spa

清除線程

這一步會刪掉標記出的未引用對象。3d

v2-4ba8fae59eec97561c7785bd9b9f0034_hd.jpg

內存分配器會保留指向可用內存的引用,以供分配新對象。指針

壓縮

爲了提高性能,刪除了未引用對象後,還能夠將剩下的已引用對象放在一塊兒(壓縮),這樣就能更簡單快捷地分配新對象了。

v2-a43e5d139d0413602f291c83f27fe075_hd.jpg

爲何須要分代垃圾收集?

以前說過,逐一標記和壓縮 Java 虛擬機裏的全部對象很是低效:分配的對象越多,垃圾回收需時就越久。不過,根據統計,大部分的對象,其實用沒多久就不用了。

來看個例子吧。(下圖中,豎軸表明已分配的字節,而橫軸表明程序運行時間)

v2-7d52b9201acf4641bc192345d8890bf8_hd.jpg

上圖可見,存活(沒被釋放)的對象隨運行時間愈來愈少。而圖中左側的那些峯值,也代表了大部分對象其實都挺短命的。
歡迎你們關注個人公種浩【程序員追風】,文章都會在裏面更新,整理的資料也會放在裏面。

JVM 分代

根據以前的規律,就能夠用來提高 JVM 的效率了。方法是,把堆分紅幾個部分(就是所謂的分代),分別是新生代、老年代,以及永生代。

v2-c819c90f3286fb1df7a9c413b13d9756_hd.jpg

新對象會被分配在新生代內存。一旦新生代內存滿了,就會開始對死掉的對象,進行所謂的小型垃圾回收過程。一片新生代內存裏,死掉的越多,回收過程就越快;至於那些還活着的對象,此時就會老化,並最終老到進入老年代內存。

Stop the World 事件 —— 小型垃圾回收屬於一種叫 "Stop the World" 的事件。在這種事件發生時,全部的程序線程都要暫停,直到事件完成(好比這裏就是完成了全部回收工做)爲止。

老年代用來保存長時間存活的對象。一般,設置一個閾值,當達到該年齡時,年輕代對象會被移動到老年代。最終老年代也會被回收。這個事件成爲 Major GC。

Major GC 也會觸發STW(Stop the World)。一般,Major GC會慢不少,由於它涉及到全部存活對象。因此,對於響應性的應用程序,應該儘可能避免Major GC。還要注意,Major GC的STW的時長受年老代垃圾回收器類型的影響。

永久代包含JVM用於描述應用程序中類和方法的元數據。永久代是由JVM在運行時根據應用程序使用的類來填充的。此外,Java SE類庫和方法也存儲在這裏。

若是JVM發現某些類再也不須要,而且其餘類可能須要空間,則這些類可能會被回收。

v2-248e431338db00a49bd0a9bcfb65ad42_hd.png

世代垃圾收集過程

如今你已經理解了爲何堆被分紅不一樣的代,如今是時候看看這些空間是如何相互做用的。後面的圖片將介紹JVM中的對象分配和老化過程。

首先,將任何新對象分配給 eden 空間。兩個 survivor 空間都是空的。

v2-661d8cc319c1c3a6540810e9260dfc8a_hd.jpg

當 eden 空間填滿時,會觸發輕微的垃圾收集。

v2-72ba43b3fa92e10bbed1e34c88d4dcc4_hd.jpg

引用的對象被移動到第一個 survivor 空間。清除 eden 空間時,將刪除未引用的對象。

v2-19e490091c2f273b3e7479ff2be56683_hd.jpg

在下一次Minor GC中,Eden區也會作一樣的操做。刪除未被引用的對象,並將被引用的對象移動到Survivor區。然而,這裏,他們被移動到了第二個Survivor區(S1)。

此外,第一個Survivor區(S0)中,在上一次Minor GC倖存的對象,會增長年齡,並被移動到S1中。待全部倖存對象都被移動到S1後,S0和Eden區都會被清空。注意,Survivor區中有了不一樣年齡的對象。

v2-15e6ca5d0d81bad60322d1b537f88539_hd.jpg

在下一次Minor GC中,會重複一樣的操做。不過,這一次Survivor區會交換。被引用的對象移動到S0,。倖存的對象增長年齡。Eden區和S1被清空。

v2-f8208a068ebc223cf2911d94525a6fb8_hd.jpg

此幻燈片演示了 promotion。在較小的GC以後,當老化的物體達到必定的年齡閾值(在該示例中爲8)時,它們從年輕一代晉升到老一代。

v2-45812a3aa07044e249ac6f2c2a13f57a_hd.jpg

隨着較小的GC持續發生,物體將繼續被推廣到老一代空間。

v2-ac37071274701b0dd7a84b56441815bd_hd.jpg

因此這幾乎涵蓋了年輕一代的整個過程。最終,將主要對老一代進行GC,清理並最終壓縮該空間。

v2-2ed2c11e9b23c68751088a31e31d7711_hd.jpg

最後

歡迎你們一塊兒交流,喜歡文章記得關注我點個贊喲,感謝支持!

相關文章
相關標籤/搜索