1. 程式人生 > >JVM(五)垃圾回收器

JVM(五)垃圾回收器

 在java虛擬機器中,垃圾回收器不僅僅只有一種,什麼情況下該使用哪種,對效能又有什這都是麼樣的影響,這都是我們需要了解的.

        序列垃圾回收器

        並行垃圾回收器

        CMS回收器

        G1回收器

序列回收器

序列回收器是指單執行緒進行垃圾回收的回收器.每次回收時,序列回收器只有一個工作執行緒,對於並行能力較弱的計算機來說,序列回收器的專注性和獨佔性往往有更好的效能表現.序列回收器可以再新生代和老年代使用,根據作用於不同的堆空間,分為新生代序列回收器和老年代序列回收器.

如何理解獨佔:是將要進行GC回收時,程式所有的動作都停止。

使用-XX:UserSerialGC 引數可以設定新生代序列回收器和老年代序列回收器

並行回收器(ParNew回收器)

並行回收器在序列回收期基礎上做了改進,他可以使用多個執行緒同時進行垃圾回收,糴計算能力強的計算機而言,可以有效地縮短垃圾回收所需的實際時間.

ParNew回收器是一個工作在新生代的垃圾收集器,它指事件的將序列回收器多執行緒化,它的回收策略和演算法和序列回收器一樣.

使用-XX:UserParNewGC 新生代ParNew回收器,老年代則使用序列回收器ParNew回收器工作時的執行緒數量可以使用 -XX:ParallelGCThreads引數指定,一般最好和計算機的CUP相當,避免過多的執行緒影響效能.

並行回收器(ParallelGC)

新生代的ParallelGC回收器,使用了複製演算法的收集器,也是多執行緒獨佔形式的收集器,但ParallelGC回收器有個非常重要的特點,就是它非常關注系統的吞吐量.

提供了兩個非常關鍵的引數控制系統的吞吐量

-XX:MaxGCPauseMillis:設定最大垃圾收集停頓時間,可用把虛擬機器在GC停頓的時間控制在MaxGCPauseMillis範圍內,如果希望減少GC停頓時間可以將MaxGCPauseMillis設定的很小,但是會導致GC頻繁,從而增加了GC的總時間,降低了吞吐量.所以需要根據實際情況設定該值.

-XX:GCTimeRatio:設定吞吐量大小,它是一個0到100之間的整數,預設情況下它的取值是99,name系統將花費不超過1/(1+n)的時間使用者垃圾回收,也就是1/(1+99)=1%的時間.

另外還可以指定-XX:+UserAdaptiveSizePolicy 開啟自適應模式,在這種模式下,新生代的大小.eden,from/to的比例,以及晉升老年代的物件年齡引數會被自動調整,已達到在堆大小,吞吐量和停頓時間之間的平衡點.

並行回收器(ParallelOldGC回收器)

老年代ParallelOldGC回收器也是一種多執行緒的回收器,和新生代ParallelGC回收器一樣,也是一種關注吞吐量的回收器,它使用了標記壓縮演算法進行實現.

-XX:+UserParallelOldGC

-XX:+ParallelGCThreads也可以設定垃圾收集時的執行緒數量.

CMS回收器

Cms全稱為:Concurrent Mark Sweep 意為併發標記清除,它使用的是標記清除法,主要是關注系統停頓時間.

使用 -XX:+UserConcMarkSweepGC 進行設定

使用 -XX:+ConcGCThreads 設定併發執行緒數量

CMS並不是獨佔的回收器,也就是說CMS回收的過程中,應用程式仍然在不停的工作又會有新的垃圾不斷產生,所以在使用CMS得過程中應該確保應用程式的記憶體足夠可用.CMS不會等到應用程式飽和的時候才去回收垃圾,而是在某一閾值的時候開始回收,回收閾值可用指定的引數進行配置,-XXCMSInitiatingOccupancyFraction 來指定,預設值為68,也就是說老年代的空間使用率達到68%的時候,會執行CMS回收.如果記憶體使用率增長的很快,在CMS執行的過程中,已經出現了記憶體不足的情況,此時CMS回收就會失敗,虛擬機器將啟動老年代序列回收器進行垃圾回收,這會導致應用程式中斷,直到垃圾回收完成後才會正常工作,這個過程GC的停頓時間可能比較長,所以XX:CMSInitiatingOccupancyFraction的設定根據實際的情況.

之前我們在學習演算法的時候說過,標記清除法有個缺點就是存在記憶體碎片的問題,那麼CMS有個引數設定-XX:+UsrCMSCompactAtFullCollecion可以使CMS回收完成之後進行一次碎片整理,-XX:CMSFullGCsBeforeCompaction引數可以設定進行多少次CMS回收之後,對記憶體進行一次壓縮.

cms回收器的好處:
1 支援併發(系統正在執行著產生垃圾,CMS回收器也可以進行垃圾回收)
2不需要考慮的記憶體不足,因為可以設定在某個閾值進行垃圾回收(每次垃圾回收都是回收老年代的垃圾,因為新生代比較不穩定)和它並不是獨佔的垃圾回收器。
3 出現碎片的問題可以進行用這2個引數調配(1 -XX:+UseCMSCompactAtFullCollecion 2-XX:+CMSFullGCsBeforeCompaction)調配。

G1回收器

G1回收器(Garbage-First)是在jdk1.7提出的垃圾回收器,從長期目標來看是為了取代CMS回收器,G1回收器擁有獨特的垃圾回收策略,G1屬於分代垃圾回收器,區分新生代和老年代,依然有eden和from/to區,它並不要求整個eden區或者新生代,老年代的空間都連續,它使用了分割槽演算法.

並行性:G1回收期間可多執行緒同時工作.

併發性:G1擁有與應用程式交替執行能力,部分工作可與應用程式同時執行,在整個GC期間不會完全阻塞應用程式

分代GC:G1依然是一個分代的收集器,但是它是兼顧新生代和老年代一起工作,之前的垃圾收集器他們或者在新生代工作,或者在老年代工作,因此這是一個很大的不同.

空間整理:G1在回收過程中,不會像CMS那樣若干次GC後需要進行碎片整理,G1採用了有效複製物件的方式,減少空間碎片.

可預見性:由於分割槽的原因,G1可以只選取部分割槽域進行回收,縮小了回收的範圍,提升了效能.

使用-XX:+UseG1GC收集器

使用-XX:MaxGCPauseMillis指定最大停頓時間

使用-XX:ParallelGCThreads 設定並行回收的執行緒數量

G1 是1.7提出來的  最好現在先別用有坑,不過現在也在逐步的完善這個G1