JVM中的垃圾收集器


垃圾收集器

新生代收集器:Serial收集器、ParNew收集器、Parallel Scavenge收集器java

1,Serial收集器
	概念:Serial收集器是一個單線程的收集器,它在進行垃圾收集的時候,必須暫停其餘全部的工做線程,直到它蒐集結束。(Stop the world)
	優勢:簡單而高效(與其它單線存放收集器相比)
	應用:運行在Client模式下的虛擬機的默認新生代收集器。
		說明:在桌面應用中,分配給虛擬機管理的內存通常不會很大,收集幾十兆或者幾百兆的新生代,停頓的時間還不到一秒,只要不是頻繁發生,這點停頓仍是能夠接受的。
	
2,ParNew收集器
	概念:ParNew收集器其實就是Serial收集器的(並行)多線程版本,即它是使用多線程進行垃圾收集的(多條垃圾收集線程並行工做)。
	優勢:能與CMS收集器搭配工做。
	應用:運行在Server模式下的虛擬機的新生代收集器。
		說明:目前只有ParNew能夠與CMS收集器搭配使用
			
3,Parallel Scavenge收集器:吞吐量優先收集器
	概念:Parallel Scavenge收集器是一個新生代收集器,
	特色:Parallel Scavenge收集器目標是:達到一個可控制的吞吐量(Throughput)
		說明:吞吐量 = 運行代碼的時間 / (運行代碼的時間 + 垃圾收集的時間)
		重要:
			1)停頓的時間越少,就越適合與用戶交互的程序,良好的響應速度能提高用戶體驗
			2)吞吐量越高,CPU的利用率就越高,能夠儘快的完成程序的運算任務,主要適合在後臺運算而不須要太多交互的任務。
			3)GC停頓的時間是以犧牲吞吐量和新生代的空間來換取的。

老年代收集器:Serial Old收集器、Parallel Old收集器、CMS收集器算法

1,Serial Old收集器
	概念:Serial Old收集器是Serial收集器的老年代版本,它一樣是一個單線程收集器。使用標記-整理算法。
	應用:
		1)在Client模式下的虛擬機使用
		2)在Server模式下:
			2.1 與Parallel Scavenge收集器搭配使用
			2.2 做爲CMS收集器的後備預案,在併發收集失敗(Concurrent Mode Failure)時使用。

2,Parallel Old收集器
	概念:Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多線程和標記-整理算法。
	說明:從jdk1.6開始提供
	重要:在注重吞吐量或者對CPU資源敏感的場合,都優先考慮Parallel Scavenge + Parallel Old 組合。

3,CMS(Concurrent Mark Sweep)收集器
	概念:CMS收集器是一種以獲取最短回收停頓爲目標的收集器。使用標記-清除算法。
	應用:B/S系統的服務器端上

    過程:  
        1)初始標記(CMS-initial-mark):只掃描老年代中 離root對象最近 的對象並做標記,故初始標記期間雖然須要Stop the word,可是暫停的時間很短。如圖一:  
              
        2)併發標記(CMS-concurrent-mark):
			1>在初始標記的基礎上(沿着引用鏈)繼續向下追溯標記(RootsTracing)。如圖二:
			2>併發標記的線程和應用程序線程是併發執行的,故在併發標記期間,可能會有新的對象進入到老年代(新生代的對象晉升到老年代、在老年代中直接分配對象等形成的),從而致使新進入到老年代中的對象沒有被標記。
			
        3)併發預清理(CMS-concurrent-preclean):掃描在併發標記期間新進入老年代的對象,目的是爲了減小(下一階段)從新標記中的工做,由於從新標記期間會Strop the word。
          
        4)從新標記(CMS-remark):從新標記在併發標記期間遺漏的對象。  
            1>須要Stop the word,停頓時間通常會比初始標記階段的停頓時間稍長一些,但遠比並發標記的時間短。  
            2>能夠並行remark,減小暫停的時間。(開關參數 -XX:+CMSParallelRemarkEnabled)  
            3>若是remark的時間仍是比較長的話,可使用開關參數 -XX:+CMSScavengeBeforeRemark,強制JVM在remark前進行一次minor gc,這樣在必定程度上下降了CMS從新標記階段對「遺漏」對象的掃描時間。  
              
        5)併發清除(CMS-concurrent-sweep):清理垃圾對象,併發清除線程和應用程序線程是併發執行的。
          
        6)併發重設(CMS-concurrent-reset):對標記的表作清零處理,而且重置CMS收集器的其餘數據結構,等待下一次垃圾回收,併發重設線程和應用程序線程是併發執行的。

    說明:
		1)因爲GC線程在耗時最長的併發標記階段、併發清除階段、併發重設階段都是與用戶線程一塊兒工做的,因此從整體上來講,CMS收集器的gc線程是與用戶線程併發執行的。
		2)若是CMS運行期間預留的內存沒法知足程序須要,那麼就會出現一次「Concurrent Mode Failure」失敗,此時JVM將啓動後備預案:
			1>臨時啓用Serial Old收集器,從新對老年代進行gc,這樣一來,停頓時間就會很長。
			2>-XX:CMSInitiatingPermOccupancyFraction參數設置的過高就很容易致使Concurrent Mode Failure,從而致使性能降低。

JVM的Server模式與client模式啓動:

區別:client模式啓動較快,Server模式啓動較慢,可是JVM一旦運行起來後,Server模式下JVM的性能將會有很大的提高。
說明:
	1)虛擬機以client模式運行時,使用的是一個代號爲C1的輕量級編譯器,以server模式運行時JVM使用的是一個相對重量級的編譯器(代號爲C2)。
	2)C2編譯器比C1編譯器編譯的更完全,故運行時JVM的性能更高。
	3)可使用java -version 命令來查看JVM是client模式仍是server模式。
	4)兩種模式的切換能夠經過更改配置(jvm.cfg配置文件)來實現:
		32位:JAVA_HOME/jre/lib/i386/jvm.cfg 
			切換:交換 -server KNOWN 與 -client KNOWN 的前後順序便可。(前提是JAVA_HOME/jre/bin目錄下同時存在server與client兩個文件夾,分別對應着各自的jvm)
			
		64位:JAVA_HOME/jre/lib/amd64/jvm.cfg 目前64位只支持server模式
			64位jdk1.8中jvm.cfg文件:
				-server KNOWN
				-client IGNORE

圖一 圖二

相關文章
相關標籤/搜索