新生代收集器: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,從而致使性能降低。
區別: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