1、cms垃圾回收演算法在gc過程中哪幾個階段會暫停應用縣城
中間調整過幾次,先搞了幾台機器做了驗證,後來逐步推廣的。
1、調大heap區,由原來的4g,調整到5g,young區的大小不變,還是2g,這時候old區就由2g變為3g了(這樣保證old區有足夠的空間);
2、設置-XX:UseCMSInitiatingOccupancyOnly,其實這個不關這個問題,只是發現半夜CMS進行的有點頻繁,就禁止掉了悲觀策略;
3、設置CMS區回收的比例,從80%調整到75%,讓old區盡早的進行,有足夠的空間剩餘;
為什麼要有GC(垃圾回收)?
JVM通過GC來回收堆和方法區中的內存,GC的基本原理就是找到程序中不再被使用的對象,然後回收掉這些對象佔用的內存。
主要的收集器有哪些?
引用計數器和跟蹤計數器兩種。
引用計數器記錄對象是否被引用,當計數器為零時,說明對象已經不再被使用,可以進行回收。java中的對象有復雜的引用關系,不是很適合引用計數器,所以sun jdk中並沒有實現這種GC方式。
跟蹤收集器,全局記錄數據的引用狀態,基於一定的條件觸發。執行的時候,從根集合開始掃描對象的引用關系,主要有復制(copying)、標記-清除(Mark-Sweep)、標記-壓縮(Mark-Compact)那種演算法。
2、jvm垃圾收集器為什麼
JVM中垃圾的回收由垃圾收集器進行,隨著JDK的不斷升級,垃圾收集器也開發出了各種版本,垃圾收集器不斷優化的動力,就是為了實現更短的停頓。
下面是7種不同的分代收集器,如果兩個收集器之間有連線,則表示它們之間可以搭配使用;所處的區域表示屬於新生代還是老年代收集器。
1.Serial 收集器 (新生代)
最基本、歷史最悠久(JDK1.3.1之前),這是一個單線程的收集器,當該收集器運行時必須暫停其他所有的工作線程,直到它收集結束。
收集過程:暫停所有線程
演算法:復制演算法
優點:簡單高效,擁有很高的單線程收集效率
應用:Client模式下的默認新生代收集器
2.ParNew 收集器 (新生代)
Serial 的多線程版本,使用多線程進行垃圾收集
收集過程:與用戶線程並發
演算法:復制演算法
優點:在CPU多的情況下,擁有比Serial更好的效果。單CPU環境下Serial效果更好
應用:許多運行在Server模式下的虛擬機中首選的新生代收集器
3.Parallel Scavenge 收集器(新生代)
Parallel Scavenge收集器的目標是達到一個可控制的吞吐量
吞吐量 = 運行用戶代碼時間 / (運行用戶代碼時間 + 垃圾收集時間)
控制吞吐量的參數:最大垃圾收集停頓時間 -XX:MaxGCPauseMillis ; 直接設置吞吐量大小:-XX:GCTimeRatio。
MaxGCPauseMillis 的值為一個大於0的毫秒數, 最大停頓時間的縮短是以犧牲吞吐量和新生代空間來換取的。
GCTimeRatio 的值為一個大於0且小於100的整數。例如:-XX:GCTimeRatio=9 我們要求應用程序線程在整個執行時間中至少9/10是活動的(因此,GC線程佔用其餘1/10)
-XX:+UseAdaptiveSizePolicy:開啟GC自適應調節策略,自動設置新生代大小、Eden與Survior區的比例、晉升老年代對象年齡等細節參數
應用:適合在後台運算而不需要太多交互的任務
4.Serial Old 收集器 (老年代)
Serial收集器的老年代版本,也是一個單線程的收集器,使用標記-整理演算法
收集過程:暫停所有線程
演算法:標記-整理演算法
應用:主要意義是Client模式下的收集器,如果在Server模式下還有:a. JDK1.5之前的版本中與Parallel Scavenge搭配使用,b. 作為CMS收集器的後背預案在並發收集時使用
5. Parallel Old 收集器 (老年代)
Parallel Scavenge收集器的老年代版本,使用多線程和「標記-整理」演算法。
收集過程:多線程
演算法:標記-整理演算法
應用:在注重吞吐量及CPU資源敏感的場合,可以優先考慮Parallel Scavenge加Parallel Old收集器
6. CMS 收集器 (老年代)
以獲取最短回收停頓時間為目標,基於「標記-清除」演算法
收集過程:初始標記-->並發標記-->重新標記-->並發清除
初始標記、重新標記兩個步驟仍需要「Stop The World」 : 初始標記僅僅只是標記一下GC
Roots能直接關聯到的對象,速度很快;並發標記就是進行GC Roots
Tracing的過程;重新標記是為了修正並發標記期間因用戶程序繼續運作,而導致標記產生變動的那一部分對象的標記記錄。
整個過程中耗時最長的是並發標記和並發清除,這兩個過程都可以與用戶線程一起工作。所以總體上說CMS收集器內存回收過程與用戶線程一起並發執行。
演算法:標記-清除 演算法
缺點:1,對cpu資源敏感,默認啟動的回收線程數是(cpu數量+3)/4,當cpu數較少的時候,會分掉大部分的cpu去執行收集器線程,影響用戶,降低吞吐量。
2,無法處理浮動垃圾,浮動垃圾即在並發清除階段因為是並發執行,還會產生垃圾,這一部分垃圾即為浮動垃圾,要等下次收集。
3,因為使用的是「標記-清除」演算法,會產生碎片。
7. G1收集器 (整個Java堆:包括新生代和老年代)
特點:並行與並發、分代收集、空間整合、可預測的停頓
G1將整個java堆(包括新生代和老生代)劃分為多個大小固定的獨立區域,並跟蹤這些區域的垃圾堆積程度,在後台維護一個優先列表,每次根據允許的收集時間,優先回收垃圾最多的區域。
但這樣回收有一個問題:對象分配在某個區域中,但並非只被本區域的其他對象引用,而是可以與整個Java堆任意的對象發生引用關系。在做可達性分析的時候,如何避免掃描整個堆呢?
解決:區域之間的對象引用,以及其他收集器中新生代與老年代之間的對象引用,虛擬機都是使用Remembered Set來避免全堆掃描,在Remembered Set中記錄對象的引用。
收集過程:初始標記-->並發標記-->最終標記-->篩選回收。與CMS不同的是,在最終標記階段,需要停頓線程,但是可並發執行;篩選回收階段,對各個區域的回收價值和成本進行排序,按照用戶所期望的回收時間進行垃圾回收,這個階段也可以並發執行。
3、cms垃圾回收演算法在gc過程中哪幾個階段會暫停
Phase 1: Initial Mark(初始化標記)和 Phase 5: Final Remark(重新標記)這兩個階段會發生stop-the-world,暫停所有應用線程。
4、JVM的垃圾演算法有哪幾種
一、垃圾收集器概述
如上圖所示,垃圾回收演算法一共有7個,3個屬於年輕代、三個屬於年老代,G1屬於橫跨年輕代和年老代的演算法。
JVM會從年輕代和年老代各選出一個演算法進行組合,連線表示哪些演算法可以組合使用
二、各個垃圾收集器說明
1、Serial(年輕代)
年輕代收集器,可以和Serial Old、CMS組合使用
採用復制演算法
使用單線程進行垃圾回收,回收時會導致Stop The World,用戶進程停止
client模式年輕代默認演算法
GC日誌關鍵字:DefNew(Default New Generation)
圖示(Serial+Serial Old)
2、ParNew(年輕代)
新生代收集器,可以和Serial Old、CMS組合使用
採用復制演算法
使用多線程進行垃圾回收,回收時會導致Stop The World,其它策略和Serial一樣
server模式年輕代默認演算法
使用-XX:ParallelGCthreads參數來限制垃圾回收的線程數
GC日誌關鍵字:ParNew(Parallel New Generation)
圖示(ParNew + Serail Old)
3、Paralle Scavenge(年輕代)
新生代收集器,可以和Serial Old、Parallel組合使用,不能和CMS組合使用
採用復制演算法
使用多線程進行垃圾回收,回收時會導致Stop The World
關注系統吞吐量
-XX:MaxGCPauseMillis:設置大於0的毫秒數,收集器盡可能在該時間內完成垃圾回收
-XX:GCTimeRatio:大於0小於100的整數,即垃圾回收時間占總時間的比率,設置越小則希望垃圾回收所佔時間越小,CPU能花更多的時間進行系統操作,提高吞吐量
-XX:UseAdaptiveSizePolicy:參數開關,啟動後系統動態自適應調節各參數,如-Xmn、-XX:SurvivorRatio等參數,這是和ParNew收集器重要的區別
GC日誌關鍵字:PSYoungGen
4、Serial Old(年老代)
年老代收集器,可以和所有的年輕代收集器組合使用(Serial收集器的年老代版本)
採用 」標記-整理「演算法,會對垃圾回收導致的內存碎片進行整理
使用單線程進行垃圾回收,回收時會導致Stop The World,用戶進程停止
GC日誌關鍵字:Tenured
圖示(Serial+Serial Old)
5、Parallel Old(年老代)
年老代收集器,只能和Parallel Scavenge組合使用(Parallel Scavenge收集器的年老代版本)
採用 」標記-整理「演算法,會對垃圾回收導致的內存碎片進行整理
關注吞吐量的系統可以將Parallel Scavenge+Parallel Old組合使用
GC日誌關鍵字:ParOldGen
圖示(Parallel Scavenge+Parallel Old)
6、CMS(Concurrent Mark Sweep年老代)
年老代收集器,可以和Serial、ParNew組合使用
採用 」標記-清除「演算法,可以通過設置參數在垃圾回收時進行內存碎片的整理
1、:默認開啟,FullGC時進行內存碎片整理,整理時用戶進程需停止,即發生Stop The World
2、CMSFullGCsBeforeCompaction:設置執行多少次不壓縮的Full GC後,執行一個帶壓縮的(默認為0,表示每次進入Full GC時都進行碎片整理)
CMS是並發演算法,表示垃圾回收和用戶進行同時進行,但是不是所有階段都同時進行,在初始標記、重新標記階段還是需要Stop the World。CMS垃圾回收分這四個階段
1、初始標記(CMS Initial mark) Stop the World 僅僅標記一下GC Roots能直接關聯到的對象,速度快
2、並發標記(CMS concurrent mark) 進行GC Roots Tracing,時間長,不發生用戶進程停頓
3、重新標記(CMS remark) Stop the World 修正並發標記期間因用戶程序繼續運行導致標記變動的那一部分對象的標記記錄,停頓時間較長,但遠比並發標記時間短
4、並發清除(CMS concurrent sweep) 清除的同時用戶進程會導致新的垃圾,時間長,不發生用戶進程停頓
適合於對響應時間要求高的系統
GC日誌關鍵字:CMS-initial-mark、CMS-concurrent-mark-start、CMS-concurrent-mark、CMS-concurrent-preclean-start、CMS-concurrent-preclean、CMS-concurrent-sweep、CMS-concurrent-reset等等
缺點
1、對CPU資源非常敏感
2、CMS收集器無法處理浮動垃圾,即清除時用戶進程同時產生的垃圾,只能等到下次GC時回收
3、因為是使用「標記-清除」演算法,所以會產生大量碎片
圖示
7、G1
G1收集器由於沒有使用過,所以從網上找了一些教程供大家了解
並行與並發
分代收集
空間整合
可預測的停頓
5、如何指定定java cms垃圾回收
如果你的JAVA應用程序有以下幾個特點,那麼可以使用Concurrent Mark Sweep (CMS) 垃圾收集器。
希望JAVA垃圾回收器回收垃圾的時間盡可能短;
應用運行在多CPU的機器上,有足夠的CPU資源;
有比較多生命周期長的對象;
希望應用的響應時間短。
6、如何提高java虛擬機的垃圾收集器
Serial(串列GC)收集器
Serial收集器是一個新生代收集器,單線程執行,使用復制演算法。它在進行垃圾收集時,必須暫停其他所有的工作線程(用戶線程)。是Jvm client模式下默認的新生代收集器。對於限定單個CPU的環境來說,Serial收集器由於沒有線程交互的開銷,專心做垃圾收集自然可以獲得最高的單線程收集效率。
ParNew(並行GC)收集器
ParNew收集器其實就是serial收集器的多線程版本,除了使用多條線程進行垃圾收集之外,其餘行為與Serial收集器一樣。
Parallel Scavenge(並行回收GC)收集器
Parallel Scavenge收集器也是一個新生代收集器,它也是使用復制演算法的收集器,又是並行多線程收集器。parallel Scavenge收集器的特點是它的關注點與其他收集器不同,CMS等收集器的關注點是盡可能地縮短垃圾收集時用戶線程的停頓時間,而parallel Scavenge收集器的目標則是達到一個可控制的吞吐量。吞吐量= 程序運行時間/(程序運行時間 + 垃圾收集時間),虛擬機總共運行了100分鍾。其中垃圾收集花掉1分鍾,那吞吐量就是99%。
Serial Old(串列GC)收集器
Serial Old是Serial收集器的老年代版本,它同樣使用一個單線程執行收集,使用「標記-整理」演算法。主要使用在Client模式下的虛擬機。
Parallel Old(並行GC)收集器
Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程和「標記-整理」演算法。
7、HotSpot JVM支持哪些垃圾收集器
按線程
單線程:Serial、SerialOld
多線程:ParNew、Parallel Scavenge、Parallel Old、CMS、G1
按適用代
新生代: Serial、ParNew、Parallel Scavenge
老年代: SerialOld、CMS 、Parallel Old
G1可以在新生代和老年代使用
常見的組合
ParNew+CMS
Parallel Scavenge+Parallel Old