JVM垃圾收集機(jī)制
整個(gè)JVM中的GC的處理機(jī)制:對(duì)不需要的對(duì)象進(jìn)行標(biāo)記,而后進(jìn)行清除.

JDK 1.8之后將最初的永久代內(nèi)存空間取消了
取消永久代目的:是為了將HotSpot與JRockit兩個(gè)虛擬機(jī)標(biāo)準(zhǔn)聯(lián)合為一個(gè)。
在整個(gè)的JVM堆內(nèi)存之中實(shí)際上將內(nèi)存分為了三塊:
- 年輕代:新對(duì)象和沒達(dá)到一定年齡的對(duì)象都在年輕代;
- 老年代:被長(zhǎng)時(shí)間使用的對(duì)象,老年代的內(nèi)存空間應(yīng)該要比年輕代更大;
-
元空間:像一些方法中的操作臨時(shí)對(duì)象等,直接使用物理內(nèi)存;
- 最初的永久代是需要在JVM堆內(nèi)存里面進(jìn)行劃分
GC流程
所有的數(shù)據(jù)都會(huì)保存在JVM的堆內(nèi)存之中,但是在實(shí)際的開發(fā)之中經(jīng)常會(huì)創(chuàng)建許多的臨時(shí)對(duì)象,也會(huì)有一些常駐對(duì)象存在,所以為了保證GC的性能問題,對(duì)于GC
的處理流程如下圖所示

對(duì)于整個(gè)的GC流程里面,那么最需要處理的就是年輕代與老年代的內(nèi)存清理操作,而元空間(永久代)都不在GC范圍內(nèi);
當(dāng)現(xiàn)在有一個(gè)新的對(duì)象產(chǎn)生,那么對(duì)象一定需要內(nèi)存空間,于是現(xiàn)在就需要為該對(duì)象進(jìn)行內(nèi)存空間的申請(qǐng);
首先會(huì)判斷伊甸園區(qū)是否有內(nèi)存空間,如果此時(shí)有內(nèi)存空間,則直接將新對(duì)象保存在伊甸園區(qū);
但是如果此時(shí)伊甸園區(qū)的內(nèi)存空間不足,那么會(huì)自動(dòng)執(zhí)行一個(gè)MinorGC操作,將伊甸園區(qū)的無用內(nèi)存空間進(jìn)行清理,清理之后會(huì)繼續(xù)判斷伊甸園區(qū)的內(nèi)存空間是否充足?如果內(nèi)存空間充足,則將新的對(duì)象直接在伊甸園區(qū)進(jìn)行空間分配;
如果執(zhí)行了Minor GC之后發(fā)現(xiàn)伊甸園區(qū)的內(nèi)存依然不足,那么這個(gè)時(shí)候會(huì)進(jìn)行存活區(qū)判斷,如果存活區(qū)有剩余空間,則將伊甸園區(qū)的部分活躍對(duì)象保存在存活區(qū),那么隨后繼續(xù)判斷伊甸園區(qū)的內(nèi)存空間是否充足,如果充足,則在伊甸園區(qū)進(jìn)行新對(duì)象的空間分配;
如果此時(shí)存活區(qū)也已經(jīng)沒有內(nèi)存空間了,則繼續(xù)判斷老年區(qū),如果此時(shí)老年區(qū)空間充足,則將存活區(qū)中的活躍對(duì)象保存到老年代,而后存活區(qū)就會(huì)存現(xiàn)有空余空間,隨后伊甸園區(qū)將活躍對(duì)象保存在存活區(qū)之中,而后在伊甸園區(qū)里為新對(duì)象開辟空間;
如果這個(gè)時(shí)候老年代也滿了,那么這個(gè)時(shí)候?qū)a(chǎn)生M ajor GC(FullGC),進(jìn)行老年代的內(nèi)存清理。
如果老年代執(zhí)行了Full GC之后發(fā)現(xiàn)依然無法進(jìn)行對(duì)象的保存,就會(huì)產(chǎn)生OOM異?!癘utOfMemoryError”
那么請(qǐng)思考“StackOverflowError”和“OutOfMemoryError”的區(qū)別是什么呢?
