java 永久代_Java新生代、老生代和永久代详解
前言: 還是面試經(jīng)常被q,小結(jié)一下
image.png
JVM中的堆一般分為三部分,新生代、老年代和永久代。
1 新生代
主要是用來(lái)存放新生的對(duì)象。一般占據(jù)堆空間的1/3,由于頻繁創(chuàng)建對(duì)象,所以新生代會(huì)頻繁觸發(fā)MinorGC進(jìn)行垃圾回收。
新生代分為Eden區(qū)、ServivorFrom、ServivorTo三個(gè)區(qū)。
Eden區(qū):Java新對(duì)象的出生地(如果新創(chuàng)建的對(duì)象占用內(nèi)存很大則直接分配給老年代)。當(dāng)Eden區(qū)內(nèi)存不夠的時(shí)候就會(huì)觸發(fā)一次MinorGc,對(duì)新生代區(qū)進(jìn)行一次垃圾回收。
ServivorTo:保留了一次MinorGc過(guò)程中的幸存者。
ServivorFrom: 上一次GC的幸存者,作為這一次GC的被掃描者。
當(dāng)JVM無(wú)法為新建對(duì)象分配內(nèi)存空間的時(shí)候(Eden區(qū)滿(mǎn)的時(shí)候),JVM觸發(fā)MinorGc。因此新生代空間占用越低,MinorGc越頻繁。
MinorGC采用復(fù)制算法。
2 老年代
老年代的對(duì)象比較穩(wěn)定,所以MajorGC不會(huì)頻繁執(zhí)行。
觸發(fā)MinorGC的條件:
1 在進(jìn)行MajorGC之前,一般都先進(jìn)行了一次MinorGC,使得有新生代的對(duì)象進(jìn)入老年代,當(dāng)老年代空間不足時(shí)就會(huì)觸發(fā)MajorGC。
2 當(dāng)無(wú)法找到足夠大的連續(xù)空間分配給新創(chuàng)建的較大對(duì)象時(shí),也會(huì)觸發(fā)MajorGC進(jìn)行垃圾回收騰出空間。
MajorGC采用標(biāo)記—清除算法(或者標(biāo)記—整理算法)
MajorGC的耗時(shí)比較長(zhǎng),因?yàn)橐日w掃描再回收,MajorGC會(huì)產(chǎn)生內(nèi)存碎片。為了減少內(nèi)存損耗,一般需要合并或者標(biāo)記出來(lái)方便下次直接分配。
當(dāng)老年代也滿(mǎn)了裝不下的時(shí)候,就會(huì)拋出OOM。
永久代
指內(nèi)存的永久保存區(qū)域,主要存放Class和Meta(元數(shù)據(jù))的信息。
Class在被加載的時(shí)候元數(shù)據(jù)信息會(huì)放入永久區(qū)域,但是GC不會(huì)在主程序運(yùn)行的時(shí)候清除永久代的信息。所以這也導(dǎo)致永久代的信息會(huì)隨著類(lèi)加載的增多而膨脹,最終導(dǎo)致OOM。
注意: 在Java8中,永久代已經(jīng)被移除,被一個(gè)稱(chēng)為“元數(shù)據(jù)區(qū)”(元空間)的區(qū)域所取代。
元空間的本質(zhì)和永久代類(lèi)似,都是對(duì)JVM規(guī)范中方法區(qū)的實(shí)現(xiàn)。不過(guò)元空間與永久代之間最大的區(qū)別在于:元空間并不在虛擬機(jī)中,而是使用本地內(nèi)存。因此默認(rèn)情況下元空間的大小僅僅受本地內(nèi)存的大小限制。類(lèi)的元數(shù)據(jù)放入 native memory, 字符串池和類(lèi)的靜態(tài)變量放入java堆中。 這樣可以加載多少類(lèi)的元數(shù)據(jù)就不再由MaxPermSize控制, 而由系統(tǒng)的實(shí)際可用空間來(lái)控制。
MajorGC和FullGC的區(qū)別(這里參考1建議不要糾結(jié)這兩個(gè)概念的區(qū)別,而是應(yīng)該專(zhuān)注于解決問(wèn)題)
Full GC 是清理整個(gè)堆空間—包括年輕代和老年代。
Major GC 是清理老年代。
MinorGC 觸發(fā)機(jī)制
1 Eden區(qū)滿(mǎn)的時(shí)候,JVM會(huì)觸發(fā)MinorGC。
MajorGC 觸發(fā)機(jī)制
1 在進(jìn)行MajorGC之前,一般都先進(jìn)行了一次MinorGC,使得有新生代的對(duì)象進(jìn)入老年代,當(dāng)老年代空間不足時(shí)就會(huì)觸發(fā)MajorGC。
2 當(dāng)無(wú)法找到足夠大的連續(xù)空間分配給新創(chuàng)建的較大對(duì)象時(shí)(如大數(shù)組),也會(huì)觸發(fā)MajorGC進(jìn)行垃圾回收騰出空間。
Full GC觸發(fā)機(jī)制:
1 調(diào)用System.gc時(shí),系統(tǒng)建議執(zhí)行Full GC,但是不必然執(zhí)行
2 老年代空間不足
3 方法區(qū)空間不足
4 通過(guò)Minor GC后進(jìn)入老年代的平均大小大于老年代的可用內(nèi)存
5 由Eden區(qū)、survivor space1(From Space)區(qū)向survivor space2(To Space)區(qū)復(fù)制時(shí),
4 當(dāng)永久代滿(mǎn)時(shí)也會(huì)引發(fā)Full GC,會(huì)導(dǎo)致Class、Method元信息的卸載。
虛擬機(jī)給每個(gè)對(duì)象定義了一個(gè)對(duì)象年齡(Age)計(jì)數(shù)器。如果對(duì)象在 Eden 出生并經(jīng)過(guò)第一次 Minor GC 后仍然存活,并且能被 Survivor 容納的話(huà),將被移動(dòng)到 Survivor 空間中,并將對(duì)象年齡設(shè)為 1。對(duì)象在 Survivor 區(qū)中每熬過(guò)一次 Minor GC,年齡就增加 1 歲, 當(dāng)它的年齡增加到一定程度(默認(rèn)為 15 歲)時(shí),就會(huì)被晉升到老年代中。對(duì)象晉升老年代的年齡閾值,可以通過(guò)參數(shù) -XX:MaxTenuringThreshold (閾值)來(lái)設(shè)置。
總結(jié)
以上是生活随笔為你收集整理的java 永久代_Java新生代、老生代和永久代详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《暗黑破坏神:不朽》安装量突破千万:官方
- 下一篇: Java学习笔记——反射