簡介JVM的Serial及ParNew收集器

Serial:

串行收集器,JVM client模式下的默認收集器,使用複製算法,在進行垃圾回收時會暫停其他所有的工作線程(stop the world,簡稱STW)直至回收結束,因此會影響用戶的正常使用體驗,但是因爲少了多線程切換的開銷,相較於其他收集器能夠更加專注於垃圾回收,在單核場景下效率極高,並且在回收較小內存(幾十或者一兩百兆)時,停頓時間是毫秒級的。推薦使用場景:年輕代佔用幾十兆到一兩百兆的桌面應用。

使用方式:-XX:+UseSerialGC,打開該開關後,使用Serial(年輕代)+Serial Old(老年代) 組合進行GC。


ParNew:

並行收集器,Serial的多線程版本,使用多條線程進行垃圾回收,其他特性與Serial一致。需要注意的是,ParNew在單核甚至雙核環境下絕對不會有比Serial收集器更好的效果,但是隨着CPU數量的增加ParNew相較於Serial的優勢會越來越明顯,但並不是成倍增長的,原因還是那個,多線程切換開銷。

另外ParNew用於垃圾回收的線程可用參數-XX:ParallelGCThreads=n進行配置。建議n與主機邏輯cpu數一致。

使用方式:-XX:+UseParNewGC,打開該開關後,使用ParNew(年輕代)+Serial Old(老年代)組合進行GC。另外,ParNew是CMS收集器的默認年輕代收集器。


簡單比較下兩款收集器的使用效果,測試結果直接寫在註釋:

/**
 * 測試比較Serial及ParNew兩個收集器
 * -Xms2048m -Xmx2048m -XX:+PrintGCDetails -XX:+PrintFlagsFinal
 * 
 * -XX:+UseSerialGC
 * gctime:100次,耗時107.640ms
 *  
 * -XX:+UseParNewGC
 * 測試機邏輯cpu個數爲4
 * ParallelGCThreads=4
 * gctime:100次,耗時59.583ms
 * ParallelGCThreads=3
 * gctime:100次,耗時77.294ms
 * ParallelGCThreads=1
 * gctime:100次,耗時137.109ms
 * ParallelGCThreads=5(可以超過主機邏輯cpu個數,但好像並沒有意義)
 * gctime:100次,耗時76.557ms
 * 
 * 測試結論:邏輯cpu的個數越多,ParNew相比Serial收集器的優勢會越明顯,但並不是成倍增長的,因爲線程之間的頻繁切換會消耗一定時間,因此,單核cpu,甚至雙核cpu下Serial是要優於ParNew的
 * 另外,ParallelGCThreads配成與主機邏輯cpu個數一致,效果是最好的。
 * @author ljl
 */
public class TestSerialVSParNew {
	private static int _10MB = 10 * 1024 * 1024;

	public static void main(String[] args) throws InterruptedException {
		for (int i = 0; i < 500; i++) {
			//不斷往Eden區分配對象,觸發minorGC
			byte[] memory = new byte[10 * _10MB];
			Thread.sleep(100);
		}
	}
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章