JVM(六)为什么新生代有两个Survivor分区?
本文會(huì)使用排除法的手段,來(lái)講解新生代的區(qū)域劃分,從而讓讀者能夠更清晰的理解分代回收器的原理,在開(kāi)始之前我們先來(lái)整體認(rèn)識(shí)一下分代收集器。
分代收集器會(huì)把內(nèi)存空間分為:老生代和新生代兩個(gè)區(qū)域,而新生代又會(huì)分為:Eden 區(qū)和兩個(gè) Survivor區(qū)(From Survivor、To Survivor),來(lái)看內(nèi)存空間分布圖,如下:
(圖片來(lái)自 fancydeepin)
可以看出 Eden 和 Survivor 分區(qū)的默認(rèn)比例是 8:1:1,這個(gè)值可以通過(guò):–XX:SurvivorRatio 設(shè)定,默認(rèn)值: –XX:SurvivorRatio=8。
順便說(shuō)一下,新生代和老生代默認(rèn)情況下的內(nèi)存占比是 1:2,該值可以通過(guò):-XX:NewRatio 來(lái)設(shè)定。
為什么 Survivor 分區(qū)不能是 0 個(gè)?
如果 Survivor 是 0 的話,也就是說(shuō)新生代只有一個(gè) Eden 分區(qū),每次垃圾回收之后,存活的對(duì)象都會(huì)進(jìn)入老生代,這樣老生代的內(nèi)存空間很快就被占滿了,從而觸發(fā)最耗時(shí)的 Full GC ,顯然這樣的收集器的效率是我們完全不能接受的。
為什么 Survivor 分區(qū)不能是 1 個(gè)?
如果 Survivor 分區(qū)是 1 個(gè)的話,假設(shè)我們把兩個(gè)區(qū)域分為 1:1,那么任何時(shí)候都有一半的內(nèi)存空間是閑置的,顯然空間利用率太低不是最佳的方案。
但如果設(shè)置內(nèi)存空間的比例是 8:2 ,只是看起來(lái)似乎“很好”,假設(shè)新生代的內(nèi)存為 100 MB( Survivor 大小為 20 MB ),現(xiàn)在有 70 MB 對(duì)象進(jìn)行垃圾回收之后,剩余活躍的對(duì)象為 15 MB 進(jìn)入 Survivor 區(qū),這個(gè)時(shí)候新生代可用的內(nèi)存空間只剩了 5 MB,這樣很快又要進(jìn)行垃圾回收操作,顯然這種垃圾回收器最大的問(wèn)題就在于,需要頻繁進(jìn)行垃圾回收。
為什么 Survivor 分區(qū)是 2 個(gè)?
如果 Survivor 分區(qū)有 2 個(gè)分區(qū),我們就可以把 Eden、From Survivor、To Survivor 分區(qū)內(nèi)存比例設(shè)置為 8:1:1 ,那么任何時(shí)候新生代內(nèi)存的利用率都 90% ,這樣空間利用率基本是符合預(yù)期的。再者就是虛擬機(jī)的大部分對(duì)象都符合“朝生夕死”的特性,所以每次新對(duì)象的產(chǎn)生都在空間占比比較大的 Eden 區(qū),垃圾回收之后再把存活的對(duì)象方法存入 Survivor 區(qū),如果是 Survivor 區(qū)存活的對(duì)象,那么“年齡”就 +1 ,當(dāng)年齡增長(zhǎng)到 15 (可通過(guò) -XX:+MaxTenuringThreshold 設(shè)定)對(duì)象就升級(jí)到老生代。
總結(jié)
根據(jù)上面的分析可以得知,當(dāng)新生代的 Survivor 分區(qū)為 2 個(gè)的時(shí)候,不論是空間利用率還是程序運(yùn)行的效率都是最優(yōu)的,所以這也是為什么 Survivor 分區(qū)是 2 個(gè)的原因了。
總結(jié)
以上是生活随笔為你收集整理的JVM(六)为什么新生代有两个Survivor分区?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 这样写Java,同事直呼666
- 下一篇: Synchronized 的 8 种使用