摘要:是一款基于并發(fā)使用標記清除算法的垃圾回收算法,只針對老年代進行垃圾回收。收集器工作時,工作線程和用戶線程可以并發(fā)執(zhí)行,以達到降低時間的目的。并發(fā)清理清理垃圾對象,這個階段線程和用戶線程并發(fā)執(zhí)行。
背景
我們上線Java服務的時候需要對其配置一些JVM參數(shù),如堆空間大小、虛擬機棧大小、垃圾回收算法。對于年輕代和老年代我們可以配置不同的垃圾回收算法。在一些對rt要求很高的場景,服務不能有長時間的卡頓,CMS就可以運用于此場景。
Concurrent Mark Sweep,是一款基于并發(fā)、使用標記清除算法的垃圾回收算法,只針對老年代進行垃圾回收。CMS收集器工作時,GC工作線程和用戶線程可以并發(fā)執(zhí)行,以達到降低STW時間的目的。
開起VM選項-XX:+UseConcMarkSweepGC,表示對老年代的回收采用CMS。
前置知識 STW首先,我們需要厘清一個概念,即只有標記階段才需要STW。標記完成以后,需要清除的對象已經(jīng)確定,無論此時是否產(chǎn)生新的垃圾,都不影響對這些對象的清理。也就是說,清除階段是可以設計成和用戶線程并發(fā)執(zhí)行的。
JVM在暫停的時候,需要選準一個時機,由于JVM系統(tǒng)運行期間的復雜性,不可能做到隨時暫停,因此引入了安全點(safepoint)的概念:程序只有在運行到安全點的時候,才可以暫停下來。HotSpot采用主動中斷的方式,讓執(zhí)行線程在運行期輪詢是否需要暫停的標志,若需要則中斷掛起。HotSpot使用了幾條短小精煉的匯編指令便可完成安全點輪詢以及觸發(fā)線程中斷,因此對系統(tǒng)性能的影響幾乎可以忽略不計。
可達性可達性是指,如果一個對象會被至少一個程序中的可達對象通過直接或間接的方式引用,則稱該對象是可達的。更詳細地說,一個對象滿足一下兩個條件之一,即被判定為可達的。
1.本身是根對象。根(root)是指由堆以外空間訪問的對象。JVM會將以下對象標記為根:a.虛擬機棧(棧幀中的本地變量表)中引用的對象;b.方法區(qū)中的類靜態(tài)屬性引用的對象;c.方法區(qū)中的常量引用的對象;d.本地方法棧中JNI的引用對象。
2.被一個可達的對象引用。
CMS的幾個階段CMS將可達性分析分解成兩個階段:a.僅掃描與根節(jié)點直接關聯(lián)的對象; b.繼續(xù)向下掃描完所有對象。因此,標記階段也被拆分成兩個階段,即初始標記和并發(fā)標記。
CMS完整的收集過程如下:
初始標記(init-mark):僅掃描與根節(jié)點直接關聯(lián)的對象并標記,這個階段必須STW, 由于跟節(jié)點數(shù)量有限,所以這個過程非常短暫。
并發(fā)標記(concurrent-marking):與用戶線程并發(fā)標記。這個階段在初始標記的基礎上繼續(xù)向下追溯標記。在并發(fā)標記階段,用戶線程和標記線程并發(fā)執(zhí)行,所以用戶不會感受到停頓。
并發(fā)預清理(concurrent-precleaning):與用戶線程并發(fā)進行。在并發(fā)標記階段一些對象的引用已經(jīng)發(fā)生了變化,precleaning會發(fā)現(xiàn)這些引用關系的改變,并將存活的對象標記。舉個例子:如果線程A有一個指向對象X的引用,并將該引用傳遞給了線程B,CMS需要記錄下線程B持有了對象X,即使線程A已經(jīng)不存在了。precleaning是為了減少下一階段“重新標記”的工作量,因為remark階段會STW。
重新標記(remark): remark階段會STW。如果應用正在并發(fā)運行且在不斷地改變對象引用,CMS則不能準確地確定某個對象是否存活。所以CMS會在remark階段STW,從而獲取所有引用關系的改變。
并發(fā)清理(concurrent-sweeping):清理垃圾對象,這個階段GC線程和用戶線程并發(fā)執(zhí)行。
并發(fā)重置(concurrent-reset):重置CMS收集器的數(shù)據(jù)結構,做好下一次執(zhí)行GC任務的準備工作。
線上Full GC分析線上某服務的老年代配置了CMS,但卻在gc.log發(fā)現(xiàn)連續(xù)Full GC的問題。JVM參數(shù)配置如下:
-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=68
參數(shù)的意義是:在老年代到68%的時候,會觸發(fā)一次CMS GC,應該是出現(xiàn)類似如下的日志:
T20:10:37.803+0800: 3246087.559: [CMS-concurrent-mark-start] T20:10:38.463+0800: 3246088.220: [CMS-concurrent-mark: 0.661/0.661 secs] [Times: user=3.17 sys=0.56, real=0.66 secs] T20:10:38.463+0800: 3246088.220: [CMS-concurrent-preclean-start] T20:10:38.552+0800: 3246088.309: [CMS-concurrent-preclean: 0.069/0.089 secs] [Times: user=0.14 sys=0.04, real=0.09 secs]_ T20:10:38.552+0800: 3246088.309: [CMS-concurrent-abortable-preclean-start]
但線上環(huán)境的日志卻出現(xiàn)如下的情況:
老年代配置了900M,但卻在只使用了50+M的時候觸發(fā)了Full GC,而且是在短暫的時間內連續(xù)觸發(fā)。
配置了CMS卻觸發(fā)Full GC,有以下幾種可能:
大對象分配時,年輕代不夠,直接晉升到老年代,老年代空間也不夠,觸發(fā) Full GC(老年代還剩800+M,顯然不可能)
內存碎片導致(由于CMS是基于標記清除算法的,所有會導致內存碎片,但通過grep -i "cms" gc.log,JVM尚未觸發(fā)過CMS回收,所以也不存在內存碎片的說法)
CMS GC失敗導致(從gc.log并未找到concurrent mode failure的記錄,排除)
jmap -histo(人為執(zhí)行該命令)
經(jīng)筆者回憶,在中午快12點的時候確實登錄過線上機,執(zhí)行過jmap -histo:live命令,經(jīng)驗證,手動執(zhí)行jmap -histo:live,也確實會在gc.log出現(xiàn)觸發(fā) Full GC的現(xiàn)象,問題得到驗證。
原文鏈接https://segmentfault.com/a/11...
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69650.html
摘要:虛擬機所處的區(qū)域,則表示它是屬于新生代收集器還是老年代收集器。虛擬機總共運行了分鐘,其中垃圾收集花掉分鐘,那么吞吐量就是。收集器線程所占用的數(shù)量為。 本文主要從GC(垃圾回收)的角度試著對jvm中的內存分配策略與相應的垃圾收集器做一個介紹。 注:還是老規(guī)矩,本著能畫圖就不BB原則,盡量將各知識點通過思維導圖或者其他模型圖的方式進行說明。文字僅記錄額外的思考與心得,以及其他特殊情況 內存...
摘要:原文鏈接本篇是專家系列的第三篇。但是,請記住調優(yōu)是不得已時的選擇。縮短耗時的單次執(zhí)行與相比,耗時有較明顯的增加。創(chuàng)建文件過程中,進程會中斷,因此不要在正常運行時系統(tǒng)上做此操作。因此校驗結果并根據(jù)具體的服務需要,決定是否要進行調優(yōu)。 原文鏈接:http://www.cubrid.org/blog/dev-platform/how-to-tune-java-garbage-collecti...
摘要:直接顯示了一個疑似內存泄漏的問題。然后分析文件給出的信息,發(fā)現(xiàn)一個叫的類。文件里面說的內存泄漏的大概的意思就是說,這個類里面的存放的東西太多了,爆掉了。修改了代碼將調用的地方改成了單例。修改完線上跑了一段日子,后來也沒有出現(xiàn)過這樣的問題。 問題描述: ????早上去公司上班,突然就郵件一直報警,接口報異常,然后去查服務器的運行情況,發(fā)現(xiàn)java的cpu爆了.接著就開始排查問題 問題解決...
摘要:深入理解虛擬機高級特性與最佳實踐第二版讀書筆記與常見面試題總結上篇文章傳送門深入理解虛擬機之內存區(qū)域本節(jié)常見面試題推薦帶著問題閱讀,問題答案在文中都有提到如何判斷對象是否死亡兩種方法。虛引用主要用來跟蹤對象被垃圾回收的活動。 《深入理解Java虛擬機:JVM高級特性與最佳實踐(第二版》讀書筆記與常見面試題總結 上篇文章傳送門: 深入理解虛擬機之Java內存區(qū)域 本節(jié)常見面試題(推薦帶著...
閱讀 1776·2021-11-11 11:02
閱讀 1679·2021-09-22 15:55
閱讀 2483·2021-09-22 15:18
閱讀 3488·2019-08-29 11:26
閱讀 3743·2019-08-26 13:43
閱讀 2646·2019-08-26 13:32
閱讀 897·2019-08-26 10:55
閱讀 965·2019-08-26 10:27