JVM垃圾收集機制
整個JVM中的GC的處理機制:對不需要的對象進行標記,而后進行清除.
JDK 1.8之后將最初的永久代內存空間取消了
取消永久代目的:是為了將HotSpot與JRockit兩個虛擬機標準聯合為一個。
在整個的JVM堆內存之中實際上將內存分為了三塊:
- 年輕代:新對象和沒達到一定年齡的對象都在年輕代;
- 老年代:被長時間使用的對象,老年代的內存空間應該要比年輕代更大;
-
元空間:像一些方法中的操作臨時對象等,直接使用物理內存;
- 最初的永久代是需要在JVM堆內存里面進行劃分
GC流程
所有的數據都會保存在JVM的堆內存之中,但是在實際的開發之中經常會創建許多的臨時對象,也會有一些常駐對象存在,所以為了保證GC的性能問題,對于GC
的處理流程如下圖所示
對于整個的GC流程里面,那么最需要處理的就是年輕代與老年代的內存清理操作,而元空間(永久代)都不在GC范圍內;
當現在有一個新的對象產生,那么對象一定需要內存空間,于是現在就需要為該對象進行內存空間的申請;
首先會判斷伊甸園區是否有內存空間,如果此時有內存空間,則直接將新對象保存在伊甸園區;
但是如果此時伊甸園區的內存空間不足,那么會自動執行一個MinorGC操作,將伊甸園區的無用內存空間進行清理,清理之后會繼續判斷伊甸園區的內存空間是否充足?如果內存空間充足,則將新的對象直接在伊甸園區進行空間分配;
如果執行了Minor GC之后發現伊甸園區的內存依然不足,那么這個時候會進行存活區判斷,如果存活區有剩余空間,則將伊甸園區的部分活躍對象保存在存活區,那么隨后繼續判斷伊甸園區的內存空間是否充足,如果充足,則在伊甸園區進行新對象的空間分配;
如果此時存活區也已經沒有內存空間了,則繼續判斷老年區,如果此時老年區空間充足,則將存活區中的活躍對象保存到老年代,而后存活區就會存現有空余空間,隨后伊甸園區將活躍對象保存在存活區之中,而后在伊甸園區里為新對象開辟空間;
如果這個時候老年代也滿了,那么這個時候將產生M ajor GC(FullGC),進行老年代的內存清理。
如果老年代執行了Full GC之后發現依然無法進行對象的保存,就會產生OOM異常“OutOfMemoryError”
那么請思考“StackOverflowError”和“OutOfMemoryError”的區別是什么呢?