#jvm内存及GC机制#
轉(zhuǎn)載
?
1 為什么要有Survivor區(qū)
先不去想為什么有兩個(gè)Survivor區(qū),第一個(gè)問題是,設(shè)置Survivor區(qū)的意義在哪里??
如果沒有Survivor,Eden區(qū)每進(jìn)行一次Minor GC,存活的對(duì)象就會(huì)被送到老年代。老年代很快被填滿,觸發(fā)Major GC(因?yàn)镸ajor GC一般伴隨著Minor GC,也可以看做觸發(fā)了Full GC)。老年代的內(nèi)存空間遠(yuǎn)大于新生代,進(jìn)行一次Full GC消耗的時(shí)間比Minor GC長(zhǎng)得多。你也許會(huì)問,執(zhí)行時(shí)間長(zhǎng)有什么壞處?頻發(fā)的Full GC消耗的時(shí)間是非常可觀的,這一點(diǎn)會(huì)影響大型程序的執(zhí)行和響應(yīng)速度,更不要說某些連接會(huì)因?yàn)槌瑫r(shí)發(fā)生連接錯(cuò)誤了。
好,那我們來想想在沒有Survivor的情況下,有沒有什么解決辦法,可以避免上述情況:
| 增加老年代空間 | 更多存活對(duì)象才能填滿老年代。降低Full GC頻率 | 隨著老年代空間加大,一旦發(fā)生Full GC,執(zhí)行所需要的時(shí)間更長(zhǎng) |
| 減少老年代空間 | Full GC所需時(shí)間減少 | 老年代很快被存活對(duì)象填滿,Full GC頻率增加 |
顯而易見,沒有Survivor的話,上述兩種解決方案都不能從根本上解決問題。
我們可以得到第一條結(jié)論:Survivor的存在意義,就是減少被送到老年代的對(duì)象,進(jìn)而減少Full GC的發(fā)生,Survivor的預(yù)篩選保證,只有經(jīng)歷16次Minor GC還能在新生代中存活的對(duì)象,才會(huì)被送到老年代。
2 為什么要設(shè)置兩個(gè)Survivor區(qū)
設(shè)置兩個(gè)Survivor區(qū)最大的好處就是解決了碎片化,下面我們來分析一下。
為什么一個(gè)Survivor區(qū)不行?第一部分中,我們知道了必須設(shè)置Survivor區(qū)。假設(shè)現(xiàn)在只有一個(gè)survivor區(qū),我們來模擬一下流程:?
剛剛新建的對(duì)象在Eden中,一旦Eden滿了,觸發(fā)一次Minor GC,Eden中的存活對(duì)象就會(huì)被移動(dòng)到Survivor區(qū)。這樣繼續(xù)循環(huán)下去,下一次Eden滿了的時(shí)候,問題來了,此時(shí)進(jìn)行Minor GC,Eden和Survivor各有一些存活對(duì)象,如果此時(shí)把Eden區(qū)的存活對(duì)象硬放到Survivor區(qū),很明顯這兩部分對(duì)象所占有的內(nèi)存是不連續(xù)的,也就導(dǎo)致了內(nèi)存碎片化。?
我繪制了一幅圖來表明這個(gè)過程。其中色塊代表對(duì)象,白色框分別代表Eden區(qū)(大)和Survivor區(qū)(小)。Eden區(qū)理所當(dāng)然大一些,否則新建對(duì)象很快就導(dǎo)致Eden區(qū)滿,進(jìn)而觸發(fā)Minor GC,有悖于初衷。?
碎片化帶來的風(fēng)險(xiǎn)是極大的,嚴(yán)重影響JAVA程序的性能。堆空間被散布的對(duì)象占據(jù)不連續(xù)的內(nèi)存,最直接的結(jié)果就是,堆中沒有足夠大的連續(xù)內(nèi)存空間,接下去如果程序需要給一個(gè)內(nèi)存需求很大的對(duì)象分配內(nèi)存。。。畫面太美不敢看。。。這就好比我們爬山的時(shí)候,背包里所有東西緊挨著放,最后就可能省出一塊完整的空間放相機(jī)。如果每件行李之間隔一點(diǎn)空隙亂放,很可能最后就要一路把相機(jī)掛在脖子上了。
那么,順理成章的,應(yīng)該建立兩塊Survivor區(qū),剛剛新建的對(duì)象在Eden中,經(jīng)歷一次Minor GC,Eden中的存活對(duì)象就會(huì)被移動(dòng)到第一塊survivor space S0,Eden被清空;等Eden區(qū)再滿了,就再觸發(fā)一次Minor GC,Eden和S0中的存活對(duì)象又會(huì)被復(fù)制送入第二塊survivor space S1(這個(gè)過程非常重要,因?yàn)檫@種復(fù)制算法保證了S1中來自S0和Eden兩部分的存活對(duì)象占用連續(xù)的內(nèi)存空間,避免了碎片化的發(fā)生)。S0和Eden被清空,然后下一輪S0與S1交換角色,如此循環(huán)往復(fù)。如果對(duì)象的復(fù)制次數(shù)達(dá)到16次,該對(duì)象就會(huì)被送到老年代中。下圖中每部分的意義和上一張圖一樣,就不加注釋了。?
?
上述機(jī)制最大的好處就是,整個(gè)過程中,永遠(yuǎn)有一個(gè)survivor space是空的,另一個(gè)非空的survivor space無碎片。
那么,Survivor為什么不分更多塊呢?比方說分成三個(gè)、四個(gè)、五個(gè)?顯然,如果Survivor區(qū)再細(xì)分下去,每一塊的空間就會(huì)比較小,很容易導(dǎo)致Survivor區(qū)滿,因此,我認(rèn)為兩塊Survivor區(qū)是經(jīng)過權(quán)衡之后的最佳方案。
說明?
本人水平有限,不當(dāng)之處希望各位高手指正。另外,文中的插圖都是我自己在word的smart art中繪制的,看起來不精致請(qǐng)見諒。?
如有轉(zhuǎn)載請(qǐng)注明出處?
http://blog.csdn.net/antony9118/article/details/51425581
轉(zhuǎn)載于:https://www.cnblogs.com/tnt-33/p/8473886.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的#jvm内存及GC机制#的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git详解之五 分布式Git
- 下一篇: pm2-zabbix 安装与配置