年轻代为什么要设置两个Survivor区
設置兩個Survivor區(qū)最大的好處就是解決了碎片化。
為什么一個Survivor區(qū)不行?第一部分中,我們知道了必須設置Survivor區(qū)。假設現(xiàn)在只有一個survivor區(qū),我們來模擬一下流程:?
剛剛新建的對象在Eden中,一旦Eden滿了,觸發(fā)一次Minor GC,Eden中的存活對象就會被移動到Survivor區(qū)。這樣繼續(xù)循環(huán)下去,下一次Eden滿了的時候,問題來了,此時進行Minor GC,Eden和Survivor各有一些存活對象,如果此時把Eden區(qū)的存活對象硬放到Survivor區(qū),很明顯這兩部分對象所占有的內存是不連續(xù)的,也就導致了內存碎片化。?
我繪制了一幅圖來表明這個過程。其中色塊代表對象,白色框分別代表Eden區(qū)(大)和Survivor區(qū)(小)。Eden區(qū)理所當然大一些,否則新建對象很快就導致Eden區(qū)滿,進而觸發(fā)Minor GC,有悖于初衷。
碎片化帶來的風險是極大的,嚴重影響Java程序的性能。堆空間被散布的對象占據(jù)不連續(xù)的內存,最直接的結果就是,堆中沒有足夠大的連續(xù)內存空間,接下去如果程序需要給一個內存需求很大的對象分配內存。。。畫面太美不敢看。。。這就好比我們爬山的時候,背包里所有東西緊挨著放,最后就可能省出一塊完整的空間放相機。如果每件行李之間隔一點空隙亂放,很可能最后就要一路把相機掛在脖子上了。
那么,順理成章的,應該建立兩塊Survivor區(qū),剛剛新建的對象在Eden中,經歷一次Minor GC,Eden中的存活對象就會被移動到第一塊survivor space S0,Eden被清空;等Eden區(qū)再滿了,就再觸發(fā)一次Minor GC,Eden和S0中的存活對象又會被復制送入第二塊survivor space S1(這個過程非常重要,因為這種復制算法保證了S1中來自S0和Eden兩部分的存活對象占用連續(xù)的內存空間,避免了碎片化的發(fā)生)。S0和Eden被清空,然后下一輪S0與S1交換角色,如此循環(huán)往復。如果對象的復制次數(shù)達到16次,該對象就會被送到老年代中。下圖中每部分的意義和上一張圖一樣,就不加注釋了。?
上述機制最大的好處就是,整個過程中,永遠有一個survivor space是空的,另一個非空的survivor space無碎片。
總結
以上是生活随笔為你收集整理的年轻代为什么要设置两个Survivor区的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一条SQL语句执行得很慢的原因有哪些?
- 下一篇: 动态代理实现代码