1. 程式人生 > >JVM 垃圾回收GC

JVM 垃圾回收GC

一、如何判斷物件是垃圾物件

     1.引用計數法

            在物件中新增一個引用計數器,當有地方引用這個物件的時候,引用計數器的值+1,失效則-1。但是兩個相互引用的物件有可能無法回收。

private Object instance;
Demo demo1 = new Demo();
Demo demo2 = new Demo();
demo1.instance = demo2;
demo2.instance = demo1;
demo2 = null;
demo1 = null;
System.gc();

     2.可達性分析

    根據GCRoots節點來搜尋,遍歷過得路徑,當物件不再引用鏈上,則物件可以被回收(沒有被引用)。

    GCRoots物件:

        虛擬機器棧、方法去中類屬性引用的物件、方法區中常量引用的物件、本地方法棧中引用的物件。

二、如何回收

     1.回收策略

         (1)標記-清除

               1.標記:標記出需要回收的物件

               2.清除:清除無效的物件       

           缺點:清除物件過程中,將物件記憶體佔用的記憶體清空,但不會整理記憶體空間,這導致記憶體的地址是不連續的。當需要分配新物件的記憶體時,需要在記憶體的一張維護表裡面尋找可用的連續的記憶體,如果沒有找到則會觸發GC。 這樣會造成效率的浪費和空間記憶體的浪費。  

         (2)複製

            堆記憶體分為 一個eden和兩個survivor區域,記憶體比例是8:1:1。在未發生GC前,記憶體中產生的物件儲存在eden區域和一個Survivor區域。當著兩個區域都存滿時,會觸發GC,將存活下來的物件例項儲存到第二個survivor區域。這個區域和eden區域將會作為新的記憶體區域來存放新產生的物件。

       (3)標記-整理 (針對老年代回收的演算法)

             標記需要清除的物件,將需要清除的物件和保留的物件移動至兩個區域,進而清除物件。這樣的演算法可以使得清楚後的記憶體區域是完整連續的區域。

         (4)分代收集演算法

             分代收集演算法是根據不用的區域採用不用的演算法來進行GC,新生代區域採用複製演算法,老年代採用標記-整理演算法。這樣的分配規則使得不同區域的GC效能更加高效。