JVM垃圾回收

如何判定垃圾對象:

  • 引用計數法
    • 爲每一個對象添加一個引用計數器,當有地方對該對象有引用的時候,引用計數器+1,當引用失效的時候,引用計數器-1
    • 直到引用計數爲0,該對象就變爲了無用的對象
    • 優點:算法簡單,效率高
    • 缺點:不能解決循環引用的垃圾對象的情況
    • 打印GC收集的日誌配置參數:-verbose:gc -XX:+PrintGCDetails
  • 可達性分析法
    • 把程序在堆中創建的對象看作一張圖,以棧中GC Root爲跟,向下尋找引用對象,如果每一個對象都直接或間接的和GC Root有關聯,則不是垃圾對象;如果尋找完畢之後,和GC Root沒有關係的對象,即爲垃圾對象
    • HotSpot VM採用的就是這種分析算法,大部分虛擬機都採用這種算法
    • 可以解決循環依賴的垃圾對象的回收
    • 什麼可以作爲GC Root呢?
      • 虛擬機棧中棧幀中的局部變量表存儲的對象句柄
      • 方法區的類屬性所引用的對象
      • 方法區中常量所引用的對象
      • 本地方法棧中引用的對象

 回收策略:

  • 標記-清除算法
    • 利用引用計數法或者可達性分析法判定出無用的對象之後,對無用的對象進行標記,然後清空
    • 缺點
      • 空間問題:堆內存會產生大量的內存碎片,一方面造成了空間的浪費;
      • 效率問題:二如果要分配一塊大的內存,還需要第二次觸發GC,進行兩次回收,效率低下;
  • 複製算法
    • 將堆區劃分爲兩個區域,先使用其中的一塊進行創建對象,垃圾回收的時候,將其中有用的對象複製到另一塊區域整理好,無用的對象不需要管,將第一塊區域全部清空
    • 缺點
      • 不能充分的利用內存空間
  • 標記-整理算法
    • 主要針對不經常回收的區域,比如老年代
    • 兩塊內存區域A和B,將A中需要清楚的對象移動到B中,將B中有用的對象移動到A中,這樣一來B中就全爲垃圾對象,直接清空就可以了
  • 分代收集算法
    • 分代回收垃圾機制,是基於這樣一個事實:不同的對象,有不同的生命週期,因此呢,不同的生命週期的對象採用不同的回收算法,可以提高回收效率;JVM把堆內存劃分爲以下四塊:
      • Eden區(新生代):所有剛創建的對象都放到Eden區域中,Eden的目的就是清除掉那些生命週期短的對象,對應Minor GC,採用效率較高的複製算法;
      • Survivor1、Survivor2區(存活區):Eden區採用複製算法用到這兩個區域進行復制以及清除;
      • Tenured Gen(老年代):當經歷過15次(默認)垃圾回收以然還存活的對象,將其放入老年代,老年代中存放的都是一些生命週期較長的對象,對應Major GC/Full GC(全部區域),因爲這一塊區域垃圾回收的頻率相對較低一點,因此採用標記-整理算法;
    •  

       

    •  垃圾回收過程:

      •  

        1.新創建的對象都存儲在Eden中;

        2.當Eden區存儲達到一定比例之後,會觸發Minor GC,將有用的對象複製到Survivor1中,清空Eden區;

        3.當Eden區再次滿之後,將Eden和Survivor1中有用的對象複製到Survivor2中,同時清空Eden區和Survivor1區;

        4.當Survivor區中對象經歷過15次(默認)垃圾回收,就將其複製到Tenured Gen/Old區域中;

        5.當Tenured Gen區滿了,會觸發一次Full GC,進行一次全面清理。

發佈了80 篇原創文章 · 獲贊 38 · 訪問量 7721
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章