在jvm中堆空間劃分為三個(gè)代:年輕代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation)。年輕代和年老代是存儲(chǔ)動(dòng)態(tài)產(chǎn)生的對(duì)象。永久帶主要是存儲(chǔ)的是java的類(lèi)信息,包括解析得到的方法、屬性、字段等等。永久帶基本不參與垃圾回收。我們這里討論的垃圾回收主要是針對(duì)年輕代和年老代。具體如下圖。
年輕代又分成3個(gè)部分,一個(gè)eden區(qū)和兩個(gè)相同的survior區(qū)。剛開(kāi)始創(chuàng)建的對(duì)象都是放置在eden區(qū)的。分成這樣3個(gè)部分,主要是為了生命周期短的對(duì)象盡量留在年輕帶。當(dāng)eden區(qū)申請(qǐng)不到空間的時(shí)候,進(jìn)行minorGC,把存活的對(duì)象拷貝到survior。年老代主要存放生命周期比較長(zhǎng)的對(duì)象,比如緩存對(duì)象。具體jvm內(nèi)存回收過(guò)程描述如下(可以結(jié)合上圖):
1、對(duì)象在Eden區(qū)完成內(nèi)存分配
2、當(dāng)Eden區(qū)滿(mǎn)了,再創(chuàng)建對(duì)象,會(huì)因?yàn)樯暾?qǐng)不到空間,觸發(fā)minorGC,進(jìn)行young(eden+1survivor)區(qū)的垃圾回收
3、minorGC時(shí),Eden不能被回收的對(duì)象被放入到空的survivor(Eden肯定會(huì)被清空),另一個(gè)survivor里不能被GC回收的對(duì)象也會(huì)被放入這個(gè)survivor,始終保證一個(gè)survivor是空的
4、當(dāng)做第3步的時(shí)候,如果發(fā)現(xiàn)survivor滿(mǎn)了,則這些對(duì)象被copy到old區(qū),或者survivor并沒(méi)有滿(mǎn),但是有些對(duì)象已經(jīng)足夠Old,也被放入Old區(qū) XX:MaxTenuringThreshold
5、當(dāng)Old區(qū)被放滿(mǎn)的之后,進(jìn)行fullGC
在知道垃圾回收機(jī)制以后,大家可以在對(duì)jvm中堆的各個(gè)參數(shù)進(jìn)行優(yōu)化設(shè)置,來(lái)提高性能。