JAVA GC 分代
概念:
- Java GC:garbage collec,垃圾收集,回收
- GC是對JVM中的記憶體進行標記和回收,Sun公司的JDK用的虛擬機器都是HotSpot,物件化的例項是放在heap堆記憶體中的,這裡講的分代收集也是指對堆記憶體的回收。
- vm區域總體分兩類,heap區和非heap區。heap區又分:Eden Space(伊甸園)、Survivor
Space(倖存者區)、Tenured Gen(老年代-養老區)。 非heap區又分:Code Cache(程式碼快取區)、Perm
Gen(永久代)、Jvm Stack(java虛擬機器棧)、Local Method Statck(本地方法棧)。 - 新生代 GC(Minor GC):指發生在新生代的垃圾收集動作,因為 Java 物件大多都具 備朝生夕滅的特性,所以 Minor GC
非常頻繁,一般回收速度也比較快。 - 老年代 GC(Major GC / Full GC):指發生在老年代的 GC,出現了 Major GC,經常 會伴隨至少一次的
Minor GC(但非絕對的,在 ParallelScavenge 收集器的收集策略裡 就有直接進行 Major GC 的策略選擇過程)
。MajorGC 的速度一般會比 Minor GC 慢 10 倍以上。
分代收集原理:
GC的分代收集分為:年輕代、老年代、永久代。(方法區是被當做永久代的,不過JDK1.6後將被取消掉了)
年輕代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation,也就是方法區)
1.年輕代的GC(存放例項化的物件)
年輕代分為三個區:Eden和兩個存活區(Survivor0和Survivor1),分別佔記憶體的80%、10%、10%
使用“停止-複製(Stop-and-copy)”清理法(將Eden區和一個Survivor中仍然存活的物件拷貝到另一個Survivor中)
當Eden區滿時,就執行一次MinorGC,並將剩餘存活的物件都新增到Surivivor0,回收Eden中的沒有存活的物件。
當Surivivor0頁都滿了的時候,就將仍然存活的存到Surivivor1中,回收Surivivor0中的物件
Surivivor0和Surivivor1依次去存,當兩個存活區切換了幾次後(HotSpot預設是15次),將仍然存活的物件複製到老年代。
2.老年代的GC(存放較大的例項化的物件和在年輕代中存活了足夠久的物件)
老年代GC用的是標記-整理演算法,即標記存活的物件,向一端移動,保證記憶體的完整性,然後將未標記的清掉。
當老年代不夠用時,也會執行Major GC,即Full GC。
注意:如果永久代代存放的常量和類過大,無法全部放入永久代,也會觸發永久代的GC,將一部分放入老年代。
3.永久代的GC(存放常量、類)
說明:在JDK1.6版本之後,永久代就要被取消掉了,只留下年輕代和老年代。
說明:年輕代的GC是必須的,但是老年代和永久代並不是必須的,可以通過設定引數來決定是否對類進行回收。
下面是畫的一個大概的圖片: