JVM的GC概述

JVMGC概述算法

GC即垃圾回收,是指jvm用於釋放那些再也不使用的對象所佔用的內存。
在充分理解了垃圾收集算法和執行過程後,纔能有效的優化它的性能。多線程

有些垃圾收集專用於特殊的應用程序。好比,實時應用程序主要是爲了不垃圾收集中斷,而大多數OLTP應用程序則注重總體效率。
垃圾收集的目的在於清除再也不使用的對象。gc經過肯定對象是否被活動對象引用來肯定是否收集該對象。兩種經常使用的方法是引用計數和對象引用遍歷。
引用計數
引用計數存儲對特定對象的全部引用數,也就是說,當應用程序建立引用以及引用超出範圍時,jvm必須適當增減引用數。當某對象的引用數爲0時,即可以進行垃圾收集。
對象引用遍歷
早期的jvm使用引用計數,如今大多數jvm採用對象引用遍歷。對象引用遍歷從一組對象開始,沿着整個對象圖上的每條連接,遞歸肯定可到達(reachable)的對象。若是某對象不能從這些根對象的一個(至少一個)到達,則將它做爲垃圾收集。在對象遍歷階段,gc必須記住哪些對象能夠到達,以便刪除不可到達的對象,這稱爲標記(marking)對象。併發

 

基本的回收算法:jvm

空間維度:標記-清除、標記-壓縮、標記-複製、增量回收、分代回收性能

時間維度:串行回收、併發回收、並行回收優化

 

標記-清除:spa

標記清除的算法最簡單,主要是標記出來須要回收的對象,而後而後把這些對象在內存的信息清除,會產生大量內存碎片。線程

 

 

 

標記-壓縮3d

有時也叫標記-清除-壓縮收集器,這個算法是在標記-清除的算法之上進行剪切操做,將存活對象壓縮在一塊兒,減小內存碎片。因爲壓縮空間須要必定的時間,會影響垃圾收集的時間。對象

 

標記-複製

 

這個算法是把內存分配爲兩個空間,一個空間(A)用來負責裝載正常的對象信息,另一個內存空間(B)是垃圾回收用的。

每次把空間A中存活的對象所有複製到空間B裏面,在一次性的把空間A刪除。

這個算法在效率上比標記-清除-壓縮高,可是須要兩塊空間,對內存要求比較大,內存的利用率比較低。適用於短生存期的對象,持續複製長生存期的對象則致使效率下降。

 

 

 

增量回收:

增量回收器:把堆分爲多個域,每次對從一個域進行垃圾回收。這樣只會早點一小部分程序暫停。

分代回收:

基於對對象生命週期分析後得出的垃圾回收算法。把對象分爲年青代、年老代、持久代,對不一樣生命週期的對象使用不一樣的算法進行回收。

 

串行回收:

用單線程處理全部垃圾回收工做,由於無需多線程交互,因此效率比較高。可是,也沒法使用多處理器的優點,因此此收集器適合單處理器機器

 

 

並行回收:

用多線程處理全部垃圾回收工做,利用多核處理器的優點。對於空間不大的區域(如young generation),採用並行收集器停頓時間很短,回收效率高,適合高頻率執行。可是若是線程數量過多,致使線程之間頻繁調度,也會影響性能。一半並行收集的線程是處理器的個數。

 

 

併發回收:

併發收集器GC時GC線程和應用線程大部分時間是併發執行,只是在初始標記(initial mark)和二次標記(remark)時須要stop-the-world,這能夠大大縮短停頓時間(pause time),因此適用於響應時間優先的應用,減小用戶等待時間。因爲GC是和應用線程併發執行,只有在多CPU場景下才能發揮其價值,在一個N個處理器的系統上,併發收集部分使用K/N個可用處理器進行回收,通常狀況下1<=K<=N/4。在執行過程當中還會產生新的垃圾floating garbage(浮動垃圾),若是等空間滿了再開始GC,那這些新產生的垃圾就沒地方放了(併發收集器通常須要20%的預留空間用於這些浮動垃圾),這時就會啓動一次串行GC,等待時間將會很長,因此要在空間還未滿時就要啓動GC。mark和sweep操做會引發不少碎片,因此間隔一段時間須要整理整個空間,不然遇到大對象,沒有連續空間也會啓動一次串行GC。採用此收集器,收集頻率不能大,不然會影響到cpu的利用率,進而影響吞吐量。

 

 

JVMGC觸發原理

JVM的GC主要是對堆內存的回收,

通常把新生代的GC稱爲minor GC ,把老年代的GC成爲 full GC,所謂full gc會先出發一次minor gc,而後在進行老年代的GC。

首先想eden區申請分配空間,若是空間夠,就直接進行分配,不然進行一次Minor GC。

minor GC 首先會對Eden區的對象進行標記,標記出來存活的對象。而後把存活的對象copy到From空間。

若是From空間足夠,則回收eden區可回收的對象。

若是from內存空間不夠,則把From空間存活的對象複製到To區,

若是TO區的內存空間也不夠的話,則把To區存活的對象複製到老年代。

若是老年代空間也不夠(或者達到觸發老年年垃圾回收條件的話)則觸發一次full GC。

簡單方向就是Eden->From->To->Old,以下圖所示:

 

 

默認是不會對持久帶(方法區)進行垃圾回收的,設置參數可回收:-XX:+CMSClassUnloadingEnabled

 

JVM支持的GC收集器

JVM採用的是分代回收,不一樣代有不一樣的垃圾收集器

如圖所示:連線的是能夠組合使用

 

 

各個收集器的細節我就不在這裏COPY/PASTE了,SerialOld收集器在書的圖中沒有,是我後加上的,其實不多使用。

相關文章
相關標籤/搜索