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