<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JVM 怎么判斷對(duì)象已經(jīng)死了?

          共 2040字,需瀏覽 5分鐘

           ·

          2020-12-14 13:25

          在Java中程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧這三個(gè)區(qū)域隨線程而生,隨線程而滅:棧中的棧幀隨著方法的調(diào)用和退出而有條不紊的進(jìn)行著入棧和出棧的過程。


          每個(gè)棧幀分配多少內(nèi)存在類結(jié)構(gòu)確定下來時(shí)就已知的,方法結(jié)束或者線程結(jié)束內(nèi)存自然跟著回收了。


          而Java堆和方法區(qū)不一樣,一個(gè)接口中的多個(gè)實(shí)現(xiàn)類的內(nèi)存可能不一樣,每個(gè)方法的多個(gè)分支需要的內(nèi)存也可能不一樣,我們只有在程序運(yùn)行時(shí)候才知道會(huì)創(chuàng)建哪些對(duì)象,這部分內(nèi)存的分配和回收都是動(dòng)態(tài)的。


          一、判斷對(duì)象已死的算法

          1)引用計(jì)數(shù)算法


          給對(duì)象添加一個(gè)引用計(jì)數(shù)器,每當(dāng)一個(gè)地方引用它時(shí)候,計(jì)數(shù)器就加1,當(dāng)引用失效,計(jì)數(shù)器就減1;任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不可能再被使用了。


          這種方法實(shí)現(xiàn)簡(jiǎn)單,效率高,但是它很難解決對(duì)象的循環(huán)引用問題:


          public class Test {
          private static final int _1MB = 1024 *1024;
          private Object instance = null;
          public static void testGC(){ Test objectA = new Test(); Test objectB = new Test();
          objectA.instance = objectB; objectB.instance = objectA;
          objectA = null; objectB = null;
          // 假如這里發(fā)生GC,objectA和objectB會(huì)不會(huì)被回收
          }}


          2)可達(dá)性分析算法


          這個(gè)算法的基本思路是通過一系列稱為“GC Roots”(一組必須活躍的引用)作為起始點(diǎn),從這些節(jié)點(diǎn)開始向下搜索,搜索走過的路徑稱為引用鏈,

          當(dāng)一個(gè)對(duì)象到GC Roots沒有任何引用鏈時(shí)候,那么證明此對(duì)象是不可用的。

          Java語言中,做作為GC Roots的對(duì)象包括以下幾種:

          1)虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象。

          2)方法區(qū)中類靜態(tài)屬性引用的對(duì)象。

          3)方法區(qū)中常量引用的對(duì)象。

          4)本地方法棧JNI(即一般說的Native方法)引用的對(duì)象。


          二、引用

          無論是通過引用計(jì)數(shù)器算法判斷對(duì)象的引用數(shù)量,還是通過可達(dá)性分析算法判斷對(duì)象引用鏈?zhǔn)欠窨蛇_(dá),判斷對(duì)象是否可活都離不開引用,Java中將引用分為四種:


          1)強(qiáng)引用(Strong Reference)

          是指程序代碼中普遍存在的,類似“Object obj = new Object()”這類的引用,只有強(qiáng)引用還存在對(duì)象就不會(huì)被回收。

          2)軟引用(Soft Reference)

          軟引用是用來描述一些還有用但是非必須的對(duì)象。對(duì)于軟引用關(guān)聯(lián)的對(duì)象,在系統(tǒng)將于發(fā)生內(nèi)存溢出異常之前,將會(huì)把這些對(duì)象列進(jìn)回收范圍中進(jìn)行二次回收。

          3)弱引用(Weak Reference)

          也是用來描述非必須對(duì)象的,強(qiáng)度比軟引用還弱一些,被軟引用關(guān)聯(lián)的對(duì)象只能存活到下一次內(nèi)存回收之前。

          4)虛引用(Phantom Referenece)

          也成為幽靈引用和幻影引用,為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個(gè)對(duì)象被回收時(shí)收到一個(gè)系統(tǒng)通知。


          三、生存還是死亡

          即使在可達(dá)性分析算法中不可達(dá)的對(duì)象,也并非一定是“非死不可”的,這時(shí)候他們暫時(shí)處于“緩刑”階段,真正宣告一個(gè)對(duì)象死亡至少要經(jīng)歷兩個(gè)階段:


          1)如果對(duì)象在可達(dá)性分析算法中不可達(dá),那么它會(huì)被第一次標(biāo)記并進(jìn)行一次刷選,刷選的條件是是否需要執(zhí)行finalize()方法(當(dāng)對(duì)象沒有覆蓋finalize()或者finalize()方法已經(jīng)執(zhí)行過了(對(duì)象的此方法只會(huì)執(zhí)行一次)),虛擬機(jī)將這兩種情況都會(huì)視為沒有必要執(zhí)行)。

          2)如果這個(gè)對(duì)象有必要執(zhí)行finalize()方法會(huì)將其放入F-Queue隊(duì)列中,稍后GC將對(duì)F-Queue隊(duì)列進(jìn)行第二次標(biāo)記,如果在重寫finalize()方法中將對(duì)象自己賦值給某個(gè)類變量或者對(duì)象的成員變量,那么第二次標(biāo)記時(shí)候就會(huì)將它移出“即將回收”的集合。

          finalize()能做的工作,使用try-finally或者其他方式都能做到更好,更及時(shí),所以不建議使用此方法。


          四、方法區(qū)回收
          永久代中回收的內(nèi)容主要是兩部分:廢棄的常量和無用的類。判斷無用的類(類卸載)必須滿足三個(gè)條件:

          1)該類所以的實(shí)例都已經(jīng)被回收

          2)加載該類的ClassLoader被回收

          3)該類對(duì)應(yīng)的java.lang.Class對(duì)象沒有在任何地方引用,無法在任何地方通過反射訪問該類的方法

          blog.csdn.net/moHedong/java/article/details/79687878


          瀏覽 40
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  思思热高清无码播放 | 亚洲一区午夜精品 | 男人射美女,日韩欧美一区二区三区 | 2014天堂网 | 成人毛片一区二区三区无码 |