YGC前后新生代是否變大分析詳解
問(wèn)題描述
我們都知道gc是為了釋放內(nèi)存,但是你是否碰到過(guò)ygc前后新生代反增不減的情況呢?gc日志效果類(lèi)似下面的:
2016-05-18T15:06:13.011+0800: [GC [ParNew (promotion failed): 636088K->690555K(707840K), 0.2958900 secs][CMS: 1019739K->1019733K(1310720K), 2.6208600 secs] 1655820K->1655820K(2018560K), [CMS Perm : 205486K->205486K(262144K)], 2.9174390 secs] [Times: user=3.74 sys=0.01, real=2.91 secs]
從上面的gc日志來(lái)看,我們新生代使用的是ParNew,而老生代用的是CMS GC,我們注意到ParNew的效果是新生代從636088K新增到了690555K,這是什么情況?
原理分析
要解釋這個(gè)問(wèn)題,我們先要弄清楚YGC的過(guò)程,parNew是新生代的gc算法,簡(jiǎn)單來(lái)說(shuō)從gc roots開(kāi)始掃描對(duì)象,當(dāng)掃到一個(gè)只要是屬于新生代的對(duì)象就將其挪到to space,但是老的對(duì)象還不會(huì)做釋放,直到gc完成之后再看是否釋放老的對(duì)象(比如說(shuō)上面我們看到了promotion failed的關(guān)鍵字,意味著晉升失敗了,也就是說(shuō)to和old都裝不下新生代晉升來(lái)的對(duì)象,那么在這種情況下其實(shí)是不會(huì)對(duì)eden和from里的老對(duì)象做釋放的,盡管to space里已經(jīng)可能存在一份副本了),但是在gc前后不管是否晉升成功,都會(huì)對(duì)from space和to space做一個(gè)對(duì)換,也就是原來(lái)的from變成to,原來(lái)的to變成from,再來(lái)看看打印gc前后內(nèi)存變化的代碼
void GenCollectedHeap::print_heap_change(size_t prev_used) const {
if (PrintGCDetails && Verbose) {
gclog_or_tty->print(" " SIZE_FORMAT
"->" SIZE_FORMAT
"(" SIZE_FORMAT ")",
prev_used, used(), capacity());
} else {
gclog_or_tty->print(" " SIZE_FORMAT "K"
"->" SIZE_FORMAT "K"
"(" SIZE_FORMAT "K)",
prev_used / K, used() / K, capacity() / K);
}
}
size_t GenCollectedHeap::used() const {
size_t res = 0;
for (int i = 0; i < _n_gens; i++) {
res += _gens[i]->used();
}
return res;
}
size_t DefNewGeneration::used() const {
return eden()->used()
+ from()->used(); // to() is only used during scavenge
}
從上面代碼我們知道,gc之后的內(nèi)存情況是used()方法返回的,其中新生代的used方法返回的是eden+from的內(nèi)存,同樣的上面的prev_used也是這么計(jì)算的,只是發(fā)生在gc之前,這樣一來(lái),根據(jù)我上面提到的情況,在gc之后不管是否成功都會(huì)做一次from和to的swap,那么gc之前新生代的使用大小,其實(shí)是gc之前eden+from的使用大小,而gc之后的新生代的使用大小,其實(shí)是eden+原來(lái)的to現(xiàn)在是使用的大小,原來(lái)的to現(xiàn)在使用的大小其實(shí)就是在gc過(guò)程中將eden和from拷貝過(guò)來(lái)的對(duì)象所占的大小。
綜上分析你應(yīng)該知道為什么會(huì)出現(xiàn)這種情況了,其實(shí)是一種特殊情況,只有在出現(xiàn)promotion failed的情況下才會(huì)發(fā)生這樣的情況,因?yàn)樵谶@個(gè)情況下存在to里新增對(duì)象,而from和eden不會(huì)變化的情況
以上就是YGC前后新生代是否變大分析詳解的詳細(xì)內(nèi)容,更多關(guān)于YGC前后新生代是否變的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
springboot整合quartz實(shí)現(xiàn)定時(shí)任務(wù)示例
spring支持多種定時(shí)任務(wù)的實(shí)現(xiàn)。我們來(lái)介紹下使用spring的定時(shí)器和使用quartz定時(shí)器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
Java實(shí)現(xiàn)線(xiàn)程同步方法及原理詳解
這篇文章主要介紹了Java實(shí)現(xiàn)線(xiàn)程同步方法及原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
Java Mybatis架構(gòu)設(shè)計(jì)深入了解
在本篇文章里小編給大家整理的是一篇關(guān)于Java Mybatis架構(gòu)設(shè)計(jì)詳解內(nèi)容,對(duì)此有興趣的朋友們可以參考下,希望能夠給你帶來(lái)幫助2021-11-11
java基于C/S模式實(shí)現(xiàn)聊天程序(服務(wù)器)
這篇文章主要為大家詳細(xì)介紹了java基于C/S模式實(shí)現(xiàn)聊天程序的服務(wù)器篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
JVM內(nèi)存模型/內(nèi)存空間:運(yùn)行時(shí)數(shù)據(jù)區(qū)
這篇文章主要介紹了JVM內(nèi)存模型/內(nèi)存空間的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java虛擬機(jī),感興趣的朋友可以了解詳細(xì),希望能夠給你帶來(lái)幫助2021-08-08

