1. 程式人生 > >系統最常用的CMS GC mode——ParNew & CMS(Serial Old作為替補)(heap> 5g)

系統最常用的CMS GC mode——ParNew & CMS(Serial Old作為替補)(heap> 5g)

工作中 常用的 CMS  GC模式  

refer to http://iamzhongyong.iteye.com/blog/1989829

如何讀懂GC日誌:


注: CMS GC下 會在特殊情況(jvm認為記憶體不夠了concurrent mode failure,promotion fail) 轉而停下所有執行緒 去做full gc,也就是MSC(單執行緒)就是Serial Old(也算一次full gc)作為替補,慢   參考 http://www.cnblogs.com/zuoxiaolong/p/jvm8.html

另外如果算一次 full gc ,實踐中 一次 CMS 中有兩次 stop the world 就算兩次 full gc了, 而MSC Serial Old作為替補

也算full gc, my god!  http://www.tuicool.com/articles/jq2yIza

這個是之前處理過的一個線上問題,處理過程斷斷續續,經歷了兩週多的時間,中間各種嘗試,總結如下。這篇文章分三部分:

1、問題的場景和處理過程;2、GC的一些理論東西;3、看懂GC的日誌

先說一下問題吧

問題場景:線上機器在半夜會推送一個700M左右的資料,這個時候有個資料置換的過程,也就是說有700M*2的資料在heap區域中,線上系統超時比較多,導致了很嚴重(嚴重程度就不說了)的問題。

問題原因:看日誌,系統介面超時的時候,系統出現了FullGC,這個時候stop-the-world了,也就停機了。分析gc的日誌,發現有promotion failed,根據FullGC觸發的條件,這個時候就會出現FullGC了。日誌如下:

1 2 2013-11-27T03:00:53.638+080035333.562: [GC 35333.562: [ParNew (promotion failed): 1877376K->1877376K(1877376K), 15.7989680 secs]35349.361: [CMS: 2144171K->2129287K(2146304K), 10.4200280 sec s] 3514052K->2129287K(4023680K), [CMS Perm : 119979K->118652K(190132K)], 26.2193500
 secs] [Times: user=30.35 sys=5.19, real=26.22 secs]

問題解決:中間調整過幾次,先搞了幾臺機器做了驗證,後來逐步推廣的。

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)那種演算法。

跟蹤計數器的三種演算法簡介?

複製:從根集合搜掃描出存活的物件,然後將存活的物件複製到一塊新的未使用的空間中,當要回收的空間中存活的物件較少時,比較高效;

標記清除:從根集合開始掃描,對存活的物件進行標記,比較完畢後,再掃描整個空間中未標記的物件,然後進行回收,不需要對物件進行移動;

標記壓縮:標記形式和“標記清除”一樣,但是回收不存活的物件後,會把所有存活的物件在記憶體空間中進行移動,好處是減少了記憶體碎片,缺點是成本比較高;

java記憶體區域的形式是啥樣的?

新生代可用的GC?

新生代中物件存活的時間比較短,因此給予Copying演算法實現,Eden區域存放新建立的物件,S0和S1區其中一塊用於存放在Minor GC的時候作為複製存活物件的目標空間,另外一塊清空。

序列GC(Serial GC)比較適合單CPU的情況,可以通過-XX:UseSerialGC來強行制定;

並行回收GC(Parallel Scavenge),啟動的時候按照設定的引數來劃定Eden/S0/S1區域的大小,但是在執行時,會根據Minor GC的頻率、消耗時間來動態調整三個區域的大小,可以用過-XX:UseAdaptiveSizePolicy來固定大小,不進行動態調整;

並行GC(ParNew)劃分Eden、S1、S0的區域上和序列GC一樣。並行GC需要配合舊生代使用CMS GC(這是他和並行回收GC的不同)(如果配置了CMS GC的方式,那麼新生代預設採取的就是並行GC的方式);

啥時候會觸發Minor GC?

當Eden區域分配記憶體時,發現空間不足,JVM就會觸發Minor GC,程式中System.gc()也可以來觸發。

舊生代可用的GC方式有哪幾種?

序列GC(Serial MSC)、並行GC(Parallel MSC)、併發GC(CMS);

關於CMS?

採用CMS時候,新生代必須使用Serial GC或者ParNew GC兩種。CMS共有七個步驟,只有Initial Marking和Final Marking兩個階段是stop-the-world的(7phase  參考文章頂),其他步驟均和應用並行進行。持久代的GC也採用CMS,通過-XX:CMSPermGenSweepingEnabled -XX:CMSClassUnloadingEnabled來制定。在採用cms gc的情況下,ygc變慢的原因通常是由於old gen出現了大量的碎片。

為啥CMS會有記憶體碎片,如何避免?

由於在CMS的回收步驟中,沒有對記憶體進行壓縮,所以會有記憶體碎片出現,CMS提供了一個整理碎片的功能,通過-XX:UseCompactAtFullCollection來啟動此功能,啟動這個功能後,預設每次執行Full GC的時候會進行整理(也可以通過-XX:CMSFullGCsBeforeCompaction=n來制定多少次Full GC之後來執行整理),整理碎片會stop-the-world.

啥時候會觸發CMS GC?

1、舊生代或者持久代已經使用的空間達到設定的百分比時(CMSInitiatingOccupancyFraction這個設定old區,perm區也可以設定);

2、JVM自動觸發(JVM的動態策略,也就是悲觀策略)(基於之前GC的頻率以及舊生代的增長趨勢來評估決定什麼時候開始執行),如果不希望JVM自行決定,可以通過-XX:UseCMSInitiatingOccupancyOnly=true來制定;

3、設定了 -XX:CMSClassUnloadingE考慮nabled 這個則考慮Perm區;

啥時候會觸發Full GC?

一、舊生代空間不足:java.lang.outOfMemoryError:java heap space;

二、Perm空間滿:java.lang.outOfMemoryError:PermGen space;

三、CMS GC時出現promotion failed  和concurrent  mode failure(Concurrent mode failure發生的原因一般是CMS正在進行,但是由於old區記憶體不足,需要儘快回收old區裡面的死的java物件,這個時候foreground gc需要被觸發,停止所有的java執行緒,同時終止CMS,直接進行MSC。);

四、統計得到的minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間;

五、主動觸發Full GC(執行jmap -histo:live [pid])來避免碎片問題;

為啥heap小於3g不建議使用CMS GC這種方式?

1、觸發比例不好設定,設定大了,那麼剩餘的空間就少了很多,設定小了,那old區還沒放置多少東西,就要進行回收了;

2、CMS進行的時候,是並行的,也就意味著如果過於頻繁的話,會和應用的強佔CPU;

3、CMS會有記憶體 碎片問題;

4、YGC的速率變慢(由於CMS GC的實現原理,導致物件從新生代晉升到舊生代時,尋找哪裡能放下的這個步驟比ParallelOld GC是慢一些的,因此就導致了YGC速度會有一定程度的下降。);

JVM的悲觀策略是啥?

所謂的悲觀策略(http://tmalltesting.com/archives/663 我們效能測試團隊一個同學分析的案例),就是JVM不按照JVM指定的引數來進行CMS GC,而是根據記憶體情況以及之前回收的方式動態調整,自行進行GC。舊生代剩餘的空間(available)大於新生代中使用的空間(max_promotion_in_bytes),或者大於之前平均晉升的old的大小(av_promo),返回false。cms gc是每隔一個週期(預設2s)就會做一次這個檢查,如果為false,則不執行YGC,而觸發cms gc。

我們經常使用的是啥GC方式?

針對目前線上機器的情況(8G的物流記憶體),heap區一般設定在4g或者5g左右,一般是使用CMS GC,這時候:

young區使用ParNew(並行GC),Old+Perm(需要單獨設定)使用CMS,整個堆(young+old+perm)使用MSC((Mark Sweep Compact)是CMS GC演算法的Full GC演算法,單執行緒回收整個堆,回收過程有嚴格的步驟。壓縮,所以回收完理論上任何Generation都不會有記憶體碎片)壓縮回收的方式。

讀懂GC日誌?

基本上都是這種格式:回收前區域佔用的大小->回收後區域佔用的大小(區域設定的大小),佔用的時間

1、promotion failed的一段日誌

1 2 2013-11-27T03:00:53.638+080035333.562: [GC 35333.562: [ParNew (promotion failed): 1877376K->1877376K(1877376K), 15.7989680 secs]35349.361: [CMS: 2144171K->2129287K(2146304K), 10.4200280 sec s] 3514052K->2129287K(4023680K), [CMS Perm : 119979K->118652K(190132K)], 26.2193500 secs] [Times: user=30.35 sys=5.19, real=26.22 secs]

解釋如下:

1 2 3 4 5 1877376K->1877376K(1877376K), 15.7989680 secs   young區 2144171K->2129287K(2146304K), 10.4200280 sec     old區情況 3514052K->2129287K(4023680K)                     heap區情況 119979K->118652K(190132K)], 26.2193500 secs      perm區情況  [Times: user=30.35 sys=5.19, real=26.22 secs]    整個過程的時間消耗

2、一段正常的CMS的日誌

1 2 3 4 5 6 7 8 9 10 11 12 13 14 2013-11-27T04:00:12.819

相關推薦

系統常用CMS GC mode——ParNew & CMSSerial Old作為替補heap> 5g

工作中 常用的 CMS  GC模式   refer to http://iamzhongyong.iteye.com/blog/1989829 如何讀懂GC日誌: 注: CMS GC下 會在特殊情況(jvm認為記憶體不夠了concurren

Docker 常用的監控方案 - 每天5分鐘玩轉 Docker 容器技術78

ida 9.png sans 開源 健康 src 適合 nta 示例 當 Docker 部署規模逐步變大後,可視化監控容器環境的性能和健康狀態將會變得越來越重要。 在本章中,我們將討論幾個目前比較常用的容器監控工具和方案,為大家構建自己的監控系統提供參考。 首先我

為什麼CMS GC時出現Concurrent Mode Failure?

    併發收集器(concurrentcollector)指的是回收年老代和持久代時,採用多個執行緒和應用執行緒併發執行,減少應用停頓時間,但如果引數設定不當,容易出現Concurrent ModeFailure現象,此時JVM將採用停頓的方式進行full gc,整個g

常用前端框架BootStrap——柵格系統

常用 框架 pic 前端框架 bootstra 柵格 album .cn ots http://pic.cnhubei.com/space.php?uid=4614&do=album&id=1340548http://pic.cnhubei.com/spac

Hbase CMS GC 調優。

export HBASE_OPTS="-XX:+UseConcMarkSweepGC"   export HBASE_LOG_DIR=/app/hbase/logexport HBASE_PID_DIR=/app/hbase/tmpexport HBASE_HEAPSIZE=16384expor

Java之CMS GC Causes

Allocation Failure Allocation Failure happens when there isn't enough free space to create new objects in Young generation. Allocation failures triggers Y

JVM 垃圾收集器Serial +Serial Old+ParNew+Parallel Scavenge+Parallel Old+CMS+G1

  1 Seiral 收集器 特徵 是單執行緒的 在垃圾回收時,必須暫停其他所有執行緒的工作執行緒,即所謂的“Stop The World” jvm在Client模式下,預設的新生代收集器仍然是Serial收集器,雖然它有著上

Java之CMS GC的7個階段

CMS收集器的主要設計目標是:低應用停頓時間。它通過兩種方式實現這一目標: 不壓縮老年代,而是使用空閒列表來管理回收空間。 大部分標記清理工作與應用程式併發執行。 主要問題:由於不壓縮帶來的老年代堆碎片,或者在物件分配率高的情況下,都可能導致Full GC。 CMS收集器的GC週期主要由7

一次CMS GC問題排查過程理解原理+讀懂GC日誌

這個是之前處理過的一個線上問題,處理過程斷斷續續,經歷了兩週多的時間,中間各種嘗試,總結如下。這篇文章分三部分: 1、問題的場景和處理過程;2、GC的一些理論東西;3、看懂GC的日誌 先說一下問題吧 問題場景:線上機器在半夜會推送一個700M左右的資料,這個時候有個資料置換

CMS gc實踐總結

首先感謝阿寶同學的幫助,我才對這個gc演算法的調整有了一定的認識,而不是停留在過去僅僅瞭解的階段。在讀過sun的文件和跟阿寶討論之後,做個小小的總結。    CMS,全稱Concurrent Low Pause Collector,是jdk1.4後期版本開始引入的新gc演

HBase最佳實踐-CMS GC調優

HBase發展到當下,對其進行的各種優化從未停止,而GC優化更是其中的重中之重。從0.94版本提出MemStoreLAB策略、Memstore Chuck Pool策略對寫快取Memstore進行優化開始,到0.96版本提出BucketCache以及堆外記憶體方案對讀快取BlockCache進行優化,再到後

CMS gc實踐總結(糾正併發執行緒數)

首先感謝阿寶同學的幫助,我才對這個gc演算法的調整有了一定的認識,而不是停留在過去僅僅瞭解的階段。在讀過sun的文件和跟阿寶討論之後,做個小小的總結。    CMS,全稱Concurrent Low Pause Collector,是jdk1.4後期版本開始引入的新gc演算

CMS gc 實踐總結

   CMS,全稱Concurrent low pause collector,是jdk1.4後期版本開始引入的新gc演算法,在jdk5和jdk6中得到了進一步的改進,它的主要適合場景是對響應實踐的重要性需求大於吞吐量的要求,能夠承受垃圾回收執行緒和應用執行緒共享處理器資源

老年代 CMS gc回收算法 對hbase的影響

導致 重新 基本 upa 大小 異常 失敗 怎麽 new 老年代 CMS gc回收算法 對hbase的影響***** 參考鏈接: 深入研究java gc https://blog.51cto.com/12445535/2372976CMS失敗模式(CMS Failure

HBase最佳實踐-CMS GC調優gc本身參數調優

部分 實踐 lock 讀寫 cms ofo mst 更多 操作 同誌們,此部分,重要的不能再重要了1、HBase發展到當下,對其進行的各種優化從未停止,而GC優化更是其中的重中之重。hbase gc調優方向從0.94版本提出MemStoreLAB策略、Memstore Ch

JVM發生CMS GC的 5 種情況,你知道的肯定不全!

經常有同學會問,為啥我的應用 Old Gen 的使用佔比沒達到 CMSInitiatingOccupancyFraction 引數

GC 知識點補充——CMS

之前已經講過了不少有關 GC 的內容,今天準備將之前沒有細講的部分進行補充,首先要提到的就是垃圾收集器。 基礎的回收方式有三種:清除、壓縮、複製,衍生出來的垃圾收集器有: Serial 收集器 新生代收集器,使用停止複製演算法,使用一個執行緒進行 GC ,序列,其它工作執行緒暫停。 使用-XX:+UseSe

vim常用的命令

set ctr 當前 選擇 執行 其中 nbsp 關閉 跳轉 編譯示例:g++ -o hello hello.cpp -std=c++11 ,其中-std=c++11表示支持C++111新特性 按下Esc後的命令模式執行 a

Linux 中常用的目錄及文件管理命令

得到 bzip2 文件夾 操作 管理命令 內容 fig find work 一、查看文件的命令  對於一個文本文件,在linux中有多種查看方式來獲知文件內容,如直接顯示整個文本內容、分頁查看內容、或者只查看文件開頭或末尾的部分內容。在linux可以用不同的命令來實現。  

常用的Eclipse的15個快捷鍵

format 滾動 XML 鎖定 ons 高亮顯示 轉換 控制 href 1、alt+?或alt+/:自動補全代碼或者提示代碼 這個是我最得意的快捷鍵組合了,尤其是當輸入syso幾個字符之後,2個手指輕松按下這2個鍵的時候,自動就補全System.out.println()