电竞比分网-中国电竞赛事及体育赛事平台

分享

java面試之GC(垃圾收集器)

 收藏小管 2017-09-15

GC:

      gc不僅負(fù)責(zé)垃圾回收,還決定內(nèi)存分配。

      java內(nèi)存管理主要是對(duì)內(nèi)存中的對(duì)象進(jìn)行內(nèi)存的分配和回收,我們都知道當(dāng)我們創(chuàng)建一個(gè)對(duì)象時(shí),對(duì)象的引用放在棧(Stack)中,對(duì)象放在堆(heap)中,gc只回收堆里面的對(duì)象。當(dāng)gc檢測(cè)到一個(gè)堆中的一個(gè)對(duì)象不在被引用時(shí),就會(huì)對(duì)這個(gè)對(duì)象進(jìn)行回收。

      當(dāng)我們創(chuàng)建一個(gè)對(duì)象時(shí),gc就會(huì)監(jiān)視這個(gè)對(duì)象的地址,大小以及狀態(tài)。gc有特定的回收算法,通常使用有向圖來記錄管理堆中的對(duì)象,通過這種方式來確定那些對(duì)象正在被引用,那些已經(jīng)不在被引用,當(dāng)一個(gè)對(duì)象不在被引用時(shí),gc就有權(quán)回收這個(gè)對(duì)象。當(dāng)然可以使用System.gc();Runtime.getRuntime().gc();來顯示調(diào)用gc。但是java規(guī)范不保證gc不一定立即回收。

      gc可以使我們?cè)陂_發(fā)時(shí)候不用考慮內(nèi)存回收的事情了,可以防止內(nèi)存泄漏。

 

垃圾收集的實(shí)現(xiàn)種類:

    1. 引用計(jì)數(shù):

        一個(gè)A對(duì)象,如果有程序使用了這個(gè)引用對(duì)象,那么引用計(jì)數(shù)加1,當(dāng)一個(gè)對(duì)象使用完畢之后引用計(jì)數(shù)減1,那么引用計(jì)數(shù)為0的時(shí)候,則可以回收。

       他不能識(shí)別循環(huán)引用

   

     2. 跟蹤收集:

         root set :當(dāng)前正在執(zhí)行的線程;全局或者靜態(tài)變量;JVM Handles;JNDI Handles       

         從root set 開始掃描有引用的對(duì)象,如果某個(gè)對(duì)象不可以到達(dá),則說明這個(gè)對(duì)象已經(jīng)dead,GC可以對(duì)其回收。也就是說:如果A對(duì)象引用了B對(duì)象,那么虛擬機(jī)會(huì)記住這個(gè)引用路徑,同時(shí)B對(duì)象引用了C對(duì)象,那么也會(huì)記錄這個(gè)路徑如果一個(gè)對(duì)象沒有在路徑圖中,那么可以收集。

         需要維護(hù)一張引用的全景圖,增加了內(nèi)存開銷,和圖的遍歷開銷。

     3. 基于對(duì)象跟蹤的分代增量收集 :

           基于對(duì)象跟蹤:說明是由跟蹤收集發(fā)展而來的,分代是指對(duì)堆進(jìn)行了合理的劃分,

           增量收集:不是每一次全部收集,而是累積的增量收集。

     Sun的JVM將整個(gè)堆分為三代:YoungGen(新生代),OldGen(年老代),和PermGen(持久區(qū)):

           Minor GC:通常是指對(duì)新生代的回收。

           Major GC:通常是指對(duì)年老代的回收。

           Full GC:Major GC除并發(fā)gc外均需對(duì)整個(gè)堆進(jìn)行掃描和回收。

           復(fù)制拷貝算法:要拷貝大量數(shù)據(jù),不會(huì)產(chǎn)生碎片。

           標(biāo)記算法:從引用根節(jié)點(diǎn)開始標(biāo)記所有被引用的對(duì)象,把未被引用的對(duì)象清除。要遍歷所有對(duì)象,會(huì)產(chǎn)生碎片。

           young 又分為eden,survivor1(from space ),survivor2(to sapce ).youngGen區(qū)里面的對(duì)象的生命周期比較短,gc對(duì)這些對(duì)象進(jìn)行回收的時(shí)候采用復(fù)制拷貝算法。

           eden 每當(dāng)一個(gè)對(duì)象創(chuàng)建的時(shí)候分配的這個(gè)區(qū)域。當(dāng)eden無法分配時(shí),觸發(fā)一次Minor gc。gc每次回收的時(shí)候都將eden區(qū)存活的對(duì)象和survivor1中的對(duì)象拷貝到survivor2中,eden和survivor1清空;當(dāng)gc執(zhí)行下次回收的時(shí)候?qū)den和survivor2中的對(duì)象拷貝到surivor1中,清空eden和survivor2。依次這樣執(zhí)行;經(jīng)過數(shù)次回收將依然存活的對(duì)象復(fù)制到OldGen區(qū)。

          OldGen 當(dāng)對(duì)象從年輕代晉升到老年代之前,會(huì)檢測(cè)老年區(qū)的剩余空間是否大于要晉升對(duì)象的大小,如果小于則直接進(jìn)行一次Full GC,以便讓老年去騰出更多的空間,然后再進(jìn)行Minor GC,把年輕代的對(duì)象復(fù)制到老年代;如果大于,則根據(jù)條件(HandlePromotionFailure設(shè)置)進(jìn)行Minor GC 和 Full GC。

           老年區(qū)采用標(biāo)記算法,因?yàn)槔夏陞^(qū)對(duì)象的生命周期都是比較長(zhǎng)的,采用拷貝算法要拷貝大量的數(shù)據(jù)。采用標(biāo)記算法每次gc回收都要遍歷所有的對(duì)象。

          PermGen 主要存放加載進(jìn)來的類信息,包括方法,屬性,常量池等,滿了之后可能會(huì)引起out of memory 錯(cuò)誤。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多