學習筆記《垃圾回收算法》

一、垃圾回收算法

1、引用計數法

引用計數法的實現非常簡單,只需要為每個對象配備一個計數器即可。但是存在一個嚴重的問題就是不能解決循環應用的問題。因此在java的垃圾回收器中,沒有使用這種算法。

2、標記清除算法

標記清楚算法是現在垃圾回收算法的思想基礎。標記清除算法將垃圾回收分為兩個階段:標記和清除階段。

在標記階段,首先通過根節點,標記所有從根節點開始的可達對象。因此未被標記的對象就是未被引用的垃圾對象。然后在清除階段,清除未被標記的對象。標記清楚算法可能產生最大的問題就是空間碎片。

3、復制算法

與標記清除算法相比,復制算法是一種相對高效的回收方法。它的核心思想是:將原有的內存空間分為兩塊,每次只使用其中一塊,在垃圾回收時,將正在使用的內存塊中的存活對象復制到未使用的內存塊中,之后,清除正在使用的內存塊中的所有對象,交換兩個內存的角色,完成垃圾回收。

如果系統中的垃圾對象很多,復制算法需要復制的存活對象數量并不會太大。因此在真正需要垃圾回收的時刻,復制算法的效率是很高的。又由于對象是再垃圾回收過程中統一被復制到新的內存空間中,因此,可確?;厥蘸蟮膬却婵臻g是沒有碎片的。雖然有以上兩大優點,但是復制算法的代價缺點是將系統內存折半,因此,單純的復制算法也很難讓人接受。

在java的新生代串行垃圾回收器中,使用的復制算法思想。

在垃圾回收時,Eden空間的存活對象會被復制到未使用的survivor空間中(假設是to),正在使用的survivor空間(假設是from)中的年輕對象也會被復制to空間中(大對象或者老年對象直接回進入老年代,如果to空間已滿,則對象也會直接進入老年代)此時Eden空間和from空間中的剩余對象就是垃圾對象,可以直接清空,to空間則存放此次回收的存活對象。

4、標記-壓縮算法

復制算法的高效性是建立在存活對象少,垃圾對象多的前提下的。這種情況在年輕代經常發生,但是在老年代,更常見的情況大部分對象都是存活對象。如果依然使用復制算法,由于存活對象較多,復制的成本也將很高。因此,基于老年代垃圾回收的特性,需要使用新的算法。標記壓縮算法是一種老年代的回收算法,它在標記清除的算法的基礎上做了一些優化,標記壓縮算法也需要從根節點開始,對所有可達對象做一次標記。但之后,并不是清理未標記的對象,而是將所有的存活對象壓縮到內存的一端。之后,清理邊界的所有空間。這種方法即避免了碎片的產生,又不需要兩塊相同的內存空間,因此性價比較高。

5、增量算法

對大部分的垃圾回收算法而言,在垃圾回收的過程中,應用軟件將處于一種Stop the World的狀態。在Stop the World 的狀態下,應用程序的所有線程都會被掛起,暫停一切正常的工作,等待垃圾回收完成。如果垃圾回收時間很長,應用程序就會掛起很久,將會嚴重影響用戶體驗或者系統的穩定性。

增量算法的基本思想是,如果一次將所有的垃圾進行處理,需要造成系統的長時間停頓,那么久可以讓垃圾收集的線程和應用程序線程交替執行。每次垃圾收集只收集一小片區域,接著切換到應用線程??梢詼p少系統的停頓時間。但是,因為線程的切換和上下文轉換的消耗,會使得垃圾回收的成本上升,造成吞吐量的下降。

6、分代

以Hot Spot為例,新生代用復制算法,老年代用標記壓縮算法。

二、垃圾收集器的類型

按線程分,可以分為串行垃圾回收器和并行垃圾回收器。串行垃圾回收器一次只使用一個線程進行垃圾回收;并行垃圾回收器一次將開啟多個線程同時進行垃圾回收。在并行能力較強的CPU上使用并行垃圾回收器可以縮短GC的停頓時間。


按照工作模式分,可以分為并發式垃圾回收器和獨占式垃圾回收器。并發式垃圾回收器與應用程序線程交替工作,以盡可能的減少應用程序的停頓時間;獨占式垃圾回收器(Stop the World)一旦運行,就停止應用程序中的其他線程,直到垃圾回收過程完全結束。


按照碎片處理方式,可分為壓縮式垃圾回收和非壓縮式垃圾回收器。壓縮式垃圾回收器會在回收完成后,對存活的對象進行壓縮整理,消除回收后的碎片;非壓縮式的垃圾回收器,不進行這不操作。


按工作的內存區間,又可分為新生代垃圾回收器和老年代垃圾回收器。顧名思義,新生代垃圾回收器只在新生代工作;老年代垃圾回收器則工作在老年代。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虛擬機(JVM)垃圾回收器提供...
    簡欲明心閱讀 89,892評論 17 311
  • 許多高級編程語言都帶有自動垃圾回收特性,以將程序員從繁瑣復雜的內存分配和釋放工作中解脫。本文將概述常見的垃圾回收算...
    kelgon閱讀 2,084評論 2 52
  • 來自: Android夢想特工隊作者: Aaron主頁: http://www.wxtlife.com/原...
    技術特工隊閱讀 4,416評論 0 28
  • JVM架構 當一個程序啟動之前,它的class會被類裝載器裝入方法區(Permanent區),執行引擎讀取方法區的...
    cocohaifang閱讀 1,701評論 0 7
  • 從三月份找實習到現在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發崗...
    時芥藍閱讀 42,375評論 11 349