GC原理,性能調(diào)優(yōu)

GC原理,性能調(diào)優(yōu)

通過(guò)IDEA 運(yùn)行JAVA代碼,java代碼執(zhí)行過(guò)程

  1. 編譯源代碼
  2. 編譯java文件生成字節(jié)碼文件
  3. JVM 中的類加載器,加載字節(jié)碼文件
  4. JVM 中的執(zhí)行引擎找到入口方法main(),執(zhí)行其中的方法

JVM 垃圾回收

JVM回收原理,把對(duì)象分為年青代、年老代,持久代,對(duì)不同生命周期的對(duì)象使用不同的算法。(基于對(duì)對(duì)象生命周期分析)
通常我們說(shuō)的JVM內(nèi)存回收總是在指堆內(nèi)存回收,確實(shí)只有堆中的內(nèi)容是動(dòng)態(tài)生氣分配的,所以以上對(duì)象的年青代和年老代都是指的JVM的Heap空間, 而持久代則是之前提到的MethodArea,不屬于Head。

  1. GC 的基本原理:講內(nèi)存中不再被使用的對(duì)象進(jìn)行回收,GC中用于回收的方法稱為收集器,由于GC需要消耗一些資源和時(shí)間,Java在對(duì)對(duì)象的生命周期特征進(jìn)行分析后,按照新生代,舊生代的方式來(lái)對(duì)對(duì)象進(jìn)行收集,以盡可能的縮短GC對(duì)應(yīng)用造成的暫停
    1)對(duì)新生代的對(duì)象的收集稱為minor GC;
    2)對(duì)舊生代的對(duì)象的收集稱為Full GC;
    3)程序中主動(dòng)調(diào)用System.gc()強(qiáng)制執(zhí)行的GC為Full GC
    不同的對(duì)象引用類型,GC會(huì)采用不同的方法進(jìn)行回收,JVM對(duì)象的引用分為了四種類型:
  2. 強(qiáng)引用:默認(rèn)情況下,對(duì)象采用的均為強(qiáng)引用(這個(gè)對(duì)象的實(shí)例沒(méi)有其他對(duì)象引用,GC時(shí)才會(huì)被銷毀回收)
  3. 軟引用:軟引用是Java中提供的一種比較合適與緩存場(chǎng)景的應(yīng)用(只有在內(nèi)存不夠的用的情況下才會(huì)被回收)
  4. 虛引用:由于虛引用只是用來(lái)得知對(duì)象是否被GC

JVM的對(duì)象分配規(guī)則

對(duì)象優(yōu)先分配在Eden區(qū)【使用空間】,如果Eden區(qū)沒(méi)有足夠的空間時(shí),虛擬機(jī)執(zhí)行一次Minor GC【垃圾回收】。
大對(duì)象直接進(jìn)入老年代(大對(duì)象是指需要大量連續(xù)內(nèi)存空間的對(duì)象)。這樣做的目的是避免在Eden區(qū)和兩個(gè)Survivor區(qū)之間發(fā)生大量的內(nèi)存拷貝(新生代采用復(fù)制算法收集內(nèi)存)。
長(zhǎng)期存活的對(duì)象進(jìn)入老年代。虛擬機(jī)為每個(gè)對(duì)象定義了一個(gè)年齡計(jì)數(shù)器,如果對(duì)象經(jīng)過(guò)了1次Minor GC(年輕代收集)那么對(duì)象會(huì)進(jìn)入Survivor區(qū),之后每經(jīng)過(guò)一次Minor GC那么對(duì)象的年齡加1,直到達(dá)到閥值對(duì)象進(jìn)入老年區(qū)。
動(dòng)態(tài)判斷對(duì)象的年齡。如果Survivor區(qū)中相同年齡的所有對(duì)象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對(duì)象可以直接進(jìn)入老年代。
空間分配擔(dān)保。每次進(jìn)行Minor GC時(shí),JVM會(huì)計(jì)算Survivor區(qū)移至老年區(qū)的對(duì)象的平均大小,如果這個(gè)值大于老年區(qū)的剩余值大小則進(jìn)行一次Full GC,如果小于檢查HandlePromotionFailure設(shè)置,如果true則只進(jìn)行Monitor GC,如果false則進(jìn)行Full GC。

簡(jiǎn)要概括如下

  • 對(duì)象先在Eden區(qū),Eden區(qū)空間不夠時(shí)進(jìn)行新生代GC
  • 大對(duì)象和長(zhǎng)期存活的對(duì)象進(jìn)入老年代
  • JVM為每個(gè)對(duì)象設(shè)置了計(jì)數(shù)器,經(jīng)過(guò)1次新生代GC則進(jìn)入幸存者區(qū),達(dá)到年齡閾值則進(jìn)入老年區(qū)
  • 幸存者區(qū)中年齡一致的對(duì)象所占內(nèi)存大小,大于幸存者區(qū)空間一半時(shí),則大于等于此年齡的對(duì)象全部進(jìn)入老年代
  • 老年代GC通常伴隨著一次新生代GC,但不絕對(duì)

YOUNG(年輕代)

年輕代分為三個(gè)區(qū),一個(gè)Eden區(qū),兩個(gè)Survivor區(qū)。大部分對(duì)象在Eden去中生成。當(dāng)Eden區(qū)滿時(shí),還存活的對(duì)象將被復(fù)制到Survivor區(qū),當(dāng)這個(gè)Survivor區(qū)也滿的時(shí)候,從第一個(gè)Survivor的兩個(gè)區(qū)復(fù)制過(guò)來(lái)的并且此時(shí)還存活的對(duì)象,將被復(fù)制到年老區(qū)(Survivor的兩個(gè)區(qū)是對(duì)稱的,沒(méi)有先后關(guān)系,所以同一個(gè)區(qū)可能同時(shí)存在從Eden復(fù)制過(guò)來(lái)的對(duì)象,和從前一個(gè)Survivor復(fù)制過(guò)來(lái)的對(duì)象,而復(fù)制到年老區(qū)的只有從第一個(gè)Survivor去過(guò)去的對(duì)象,并且Survivor區(qū)總有一個(gè)是空的)。

Tenured 年老代

年老代存放從年輕代存活的對(duì)象,一般來(lái)說(shuō)年老代存放的都是生命周期較長(zhǎng)的對(duì)象。

持久代Perm

用于存放靜態(tài)文件,如今Java類,方法等,持久代對(duì)垃圾回收沒(méi)有明顯的影響,但是有些應(yīng)用可能動(dòng)態(tài)生成活調(diào)用一些class,列如Hibernate等,在這種時(shí)候需要設(shè)置一個(gè)比較大的持久代空間來(lái)存放這些運(yùn)行過(guò)程新增的類。持久代大小通過(guò)-XX:MaxPermSize 進(jìn)行設(shè)置。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容