JVM的GC概述算法
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的利用率,進而影響吞吐量。
JVM的GC觸發原理
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收集器在書的圖中沒有,是我後加上的,其實不多使用。