JVM系列之GC

JVM系列之GC

談到JVM懦铺,大家都知道GC(Garbage Collection),GC這個(gè)話題說淺了就一句話--JVM自動(dòng)垃圾收集,說深了就無止盡了支鸡,回收算法冬念,各種收集器,gc類型,gc觸發(fā)點(diǎn)....等等
鑒于作者才學(xué)疏淺牧挣,這篇博文還是準(zhǔn)備用通熟易懂的話把作者自己對GC這一塊的理解做陳述急前,概要如下:

文章結(jié)構(gòu)

  1. 哪些內(nèi)存需要回收(Which)
  2. 各種GC的觸發(fā)時(shí)機(jī)(When)
  3. 如何回收(How)
    3.1 回收算法
    3.2 HotSpot的具體實(shí)現(xiàn)-各種收集器
  4. GC日志

1. 哪些內(nèi)存需要回收(Which)

大多數(shù)沒干過C或者C++的Javaer是幸福的,因?yàn)闆]有體會(huì)過那種自己new delete內(nèi)存的感覺瀑构,創(chuàng)建對象就是new,不管內(nèi)存的回收問題裆针。其實(shí)我們的內(nèi)存是JVM的GC機(jī)制來幫我們回收的。那么問題來了。到底哪些內(nèi)存需要回收呢据块?
答案:可達(dá)性分析算法,說白了码邻,就是JVM預(yù)先確定一組GC roots引用變量折剃,如Student stu =new Student();這個(gè)stu就可以作為GC roots,當(dāng)進(jìn)行垃圾回收時(shí)另假,JVM通過GC Roots找到能夠引用到的所有活對象,然后把剩下的對象標(biāo)記為"無用",即可回收狀態(tài)
能夠作為GC roots的引用如下:

  • 所有Java線程當(dāng)前活躍的棧幀里指向GC堆里的對象的引用怕犁;換句話說边篮,當(dāng)前 所有正在被調(diào)用的方法的引用類型的參數(shù)/局部變量/臨時(shí)值。
  • VM的一些靜態(tài)數(shù)據(jù)結(jié)構(gòu)里指向GC堆里的對象的引用奏甫,例如說HotSpot VM里的Universe里有很多這樣的引用戈轿。
  • JNI handles,包括global handles和local handles(看情況)所有當(dāng)前被加載的Java類(看情況)Java類的引用類型靜態(tài)變量(看情況)Java類的運(yùn)行時(shí)常量池里的引用類型常量(String或Class類型)(看情況)String常量池(StringTable)里的引用

2. 各種GC的觸發(fā)時(shí)機(jī)(When)

2.1 GC類型

說到GC類型阵子,就更有意思了思杯,為什么呢,因?yàn)闃I(yè)界沒有統(tǒng)一的嚴(yán)格意義上的界限挠进,也沒有嚴(yán)格意義上的GC類型色乾,都是左邊一個(gè)教授一套名字,右邊一個(gè)作者一套名字领突。為什么會(huì)有這個(gè)情況呢暖璧,因?yàn)镚C類型是和收集器有關(guān)的,不同的收集器會(huì)有自己獨(dú)特的一些收集類型君旦。所以作者在這里引用R大關(guān)于GC類型的介紹澎办,作者覺得還是比較妥當(dāng)準(zhǔn)確的。如下:

  • Partial GC:并不收集整個(gè)GC堆的模式
    • Young GC(Minor GC):只收集young gen的GC
    • Old GC:只收集old gen的GC金砍。只有CMS的concurrent collection是這個(gè)模式
    • Mixed GC:收集整個(gè)young gen以及部分old gen的GC局蚀。只有G1有這個(gè)模式
  • Full GC(Major GC):收集整個(gè)堆,包括young gen恕稠、old gen至会、perm gen(如果存在的話)等所有部分的模式。

2.2 觸發(fā)時(shí)機(jī)

上面大家也看到了谱俭,GC類型分分類是和收集器有關(guān)的奉件,那么當(dāng)然了,對于不同的收集器昆著,GC觸發(fā)時(shí)機(jī)也是不一樣的凯傲,作者就針對默認(rèn)的serial GC來說:

  • young GC:當(dāng)young gen中的eden區(qū)分配滿的時(shí)候觸發(fā)业崖。注意young GC中有部分存活對象會(huì)晉升到old gen,所以young GC后old gen的占用量通常會(huì)有所升高。
  • full GC:當(dāng)準(zhǔn)備要觸發(fā)一次young GC時(shí)收捣,如果發(fā)現(xiàn)統(tǒng)計(jì)數(shù)據(jù)說之前young GC的平均晉升大小比目前old gen剩余的空間大困食,則不會(huì)觸發(fā)young GC而是轉(zhuǎn)為觸發(fā)full GC(因?yàn)镠otSpot VM的GC里,除了CMS的concurrent collection之外,其它能收集old gen的GC都會(huì)同時(shí)收集整個(gè)GC堆塘匣,包括young gen,所以不需要事先觸發(fā)一次單獨(dú)的young GC)巷帝;或者忌卤,如果有perm gen的話,要在perm gen分配空間但已經(jīng)沒有足夠空間時(shí)楞泼,也要觸發(fā)一次full GC驰徊;或者System.gc()、heap dump帶GC堕阔,默認(rèn)也是觸發(fā)full GC棍厂。

3. 如何回收(How)

3.1 回收算法

由于網(wǎng)上已經(jīng)擁有非常多的優(yōu)秀博文來詳細(xì)介紹關(guān)于回收算法這塊,所以這塊作者將引用其他博客的介紹并加上自己的一些描述:
3.1.1 標(biāo)記清除算法(Mark-Sweep)

3.1.2復(fù)制算法(Coping)(絕大部分收集器的新生代使用的算法)

復(fù)制算法在JVM新生代垃圾回收中的運(yùn)用:

Eden:From:TO =8:1:1
由于新生代中90%的對象都是"朝生夕死"超陆,采用復(fù)制算法是比較合理的牺弹,首先只移動(dòng)了存活下來的對象(比較少數(shù)),其次,內(nèi)存在移動(dòng)到To區(qū)域后是有順序的时呀,不存在內(nèi)存碎片张漂。
值得一提的是,假如在一次MinorGC時(shí),Eden中存活的對象+From中存活的對象>To的剩余空間退唠,則會(huì)通過擔(dān)保機(jī)制將對象直接轉(zhuǎn)移到Old gen ,如果Old gen的內(nèi)存空間也不夠鹃锈,則進(jìn)行一次Full gc .
當(dāng)對象的年齡到達(dá)15歲時(shí)會(huì)轉(zhuǎn)移到Old gen (可通過參數(shù)配置,一般不建議更改瞧预。)

3.1.3標(biāo)記-整理算法(Mark-Compact):

由于Old gen 的大部分對象都是年齡很大的對象屎债,所以存活率比較高,采用復(fù)制算法肯定是行不通的(較多的對象復(fù)制操作)垢油,所以才大部分收集器的old gen采用 Mark-Compact算法盆驹,避免了空間碎片。

3.1.4三種算法比較:

稍微解釋一下常見的關(guān)于GC時(shí)間的問題:
為什么FGC的時(shí)間比MinorGC長很多滩愁?
答:FGC進(jìn)行了old gen的gc躯喇,由于算法上采用Mark-Sweep或者M(jìn)ark-Compact,進(jìn)行了很多對象(老年代存活率很低)的移動(dòng)硝枉,當(dāng)然很耗時(shí)了廉丽!其實(shí)就是空間換時(shí)間,時(shí)間換空間的問題妻味。

3.2 HotSpot的具體實(shí)現(xiàn)-各種收集器

關(guān)于收集器這塊正压,由于本人也是JVM初學(xué)者,加上很少有在生產(chǎn)環(huán)境做收集器參數(shù)調(diào)整责球,搭配使用的機(jī)會(huì)焦履。所以可以說對于一些HotSpot收集器只是停留在
書籍與博文層次

4 GC日志

-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-Xloggc:/Users/zdy/Desktop/dump/gclog.txt

當(dāng)服務(wù)器出現(xiàn)卡頓比較頻繁時(shí)拓劝,嘗試看下自己的GC日志,注意Full gc 頻率嘉裤。

最后郑临,稍微說一下作者的心得:

  • 如果是服務(wù)器一次卡頓時(shí)間比較長,一般是full gc時(shí)間過長,而應(yīng)用最求的是卡頓(STW)時(shí)間短屑宠,可以接受多次卡頓厢洞,那么可以考慮調(diào)整加大young gen的比例,和提高進(jìn)入老年代的年齡(默認(rèn)15歲)來盡量避免FGC.
  • 選擇合適的收集器很重要侨把。要根據(jù)應(yīng)用的特點(diǎn)犀变。是追求吞吐量妹孙,還是追求最小停頓秋柄。
  • 經(jīng)常對照gc日志觀察現(xiàn)實(shí)的情況,如多長時(shí)間一卡頓蠢正,多久一卡頓骇笔,然后來調(diào)整自己的收集器或者相關(guān)的內(nèi)存比例來達(dá)到自己想要的效果。
  • 在有限的物理資源條件下嚣崭,要避免讓用戶接受過多的STW笨触,可以考慮在半夜自動(dòng)進(jìn)行g(shù)c(System.gc()),雖然不一定生效,但可以觀察下效果雹舀。多數(shù)情況下是會(huì)觸發(fā)full gc 的芦劣。
  • 大多數(shù)應(yīng)用是可以接受頻繁的mgc,但卻不能接受full gc 的長時(shí)間卡頓说榆,所以在觀察gc日志時(shí)一定要注意自己full gc的頻率和觸發(fā)條件(是由于內(nèi)存擔(dān)保虚吟,還是年齡到了,還是TO內(nèi)存太小签财,導(dǎo)致每次都fgc.).

如果您覺得這篇文章對你有幫助串慰,請點(diǎn)贊或者喜歡,讓更多的人看到唱蒸!祝你每天開心愉快邦鲫!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市神汹,隨后出現(xiàn)的幾起案子庆捺,更是在濱河造成了極大的恐慌,老刑警劉巖屁魏,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滔以,死亡現(xiàn)場離奇詭異,居然都是意外死亡蚁堤,警方通過查閱死者的電腦和手機(jī)醉者,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門但狭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人撬即,你說我怎么就攤上這事立磁。” “怎么了剥槐?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵唱歧,是天一觀的道長。 經(jīng)常有香客問我粒竖,道長颅崩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任蕊苗,我火速辦了婚禮沿后,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朽砰。我一直安慰自己尖滚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布瞧柔。 她就那樣靜靜地躺著漆弄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪造锅。 梳的紋絲不亂的頭發(fā)上撼唾,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機(jī)與錄音哥蔚,去河邊找鬼倒谷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛肺素,可吹牛的內(nèi)容都是我干的恨锚。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼倍靡,長吁一口氣:“原來是場噩夢啊……” “哼猴伶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起塌西,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤他挎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后捡需,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體办桨,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年站辉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了呢撞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片损姜。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖殊霞,靈堂內(nèi)的尸體忽然破棺而出摧阅,到底是詐尸還是另有隱情,我是刑警寧澤绷蹲,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布棒卷,位于F島的核電站,受9級特大地震影響祝钢,放射性物質(zhì)發(fā)生泄漏比规。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一拦英、第九天 我趴在偏房一處隱蔽的房頂上張望蜒什。 院中可真熱鬧,春花似錦龄章、人聲如沸吃谣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肃晚,卻和暖如春锚贱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背关串。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工拧廊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晋修。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓吧碾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親墓卦。 傳聞我的和親對象是個(gè)殘疾皇子倦春,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容