歡迎掃碼關注我 😊 算法
給對象中添加一個引用計數器,每當有一個地方引用他時就給計數器值加一;當引用失效時,計數器值就減一;任什麼時候刻計數器爲0的對象就是不可能再被使用的。數組
缺點:很難解決對象之間互相循環引用的問題。安全
以「GC Root」對象爲起始點,今後節點向下搜索,搜索所走的路徑成爲引用鏈,當一個對象和GC Root之間沒有任何引用鏈的時候,則此對象爲不可用對象。微信
如上圖所示,Object1到Object4與GC Root之間存在引用鏈,因此Object1到Object4的對象是可達對象,而Object5和Object6沒有雨GC Root相關的引用鏈,因此Object5和Object6是不可達對象,是能夠回收的對象。多線程
Java中能夠被稱爲GC Root的對象有如下幾種:併發
虛擬機棧中引用的對象線程
方法區中類靜態屬性引用的對象cdn
方法區中常量引用的對象server
本地方法棧中JNI(Native方法)引用的對象對象
強引用:相似於new一個對象的引用,只要強引用存在,垃圾收集器永遠不會回收掉被引用的對象。
軟引用:描述的是一些還有用但並不是必須的對象,對於軟引用關聯的對象,在系統將要發生內存溢出以前,會把這些對象列進回收範圍之中進行第二次回收,若是此次回收尚未足夠的內存就會拋出內存溢出異常。
弱引用:描述非必須對象,被弱引用關聯的對象只能生存到下一次垃圾收集發生以前。當垃圾收集器工做時,不管當前內存是否足夠,都會回收只被弱引用關聯的對象。
虛引用:一個對象是否有虛引用存在,徹底不會對其生存時間構成影響,也沒法經過虛引用來取得一個對象實例。爲一個對象設置虛引用關聯的惟一目的就是當這個對象被收集器收集時會收到一個系統通知。
若是一個對象在可達性分析時沒後沒有與GC Root相鏈接的引用鏈,它將會第一次標記並篩選,篩選條件是該對象是否有必要執行finalize()方法,若是有必要執行finalize()方法,對象只要從新與引用鏈上的任何一個對象創建關聯便可,拿在第二次標記時將他移除「即將回收」集合。任何對象的finalize()方法只會被調用一次,若是對象面臨下一次回收,它的finalize()方法不會被再次執行。
首先標記出全部要回收的對象,在標記完成後統一回收被標記的對象。
缺點:一、效率問題,標記和清除兩個過程的效率都不高。 二、空間問題,標記清除會產生大量不連續的內存碎片,空間碎片太多會致使之後程序運行過程當中須要分配較大對象時,沒法找到足夠的連續內存而不得進行另外一次垃圾收集動做。
將內存安容量分爲大小相等的兩塊,每次只使用其中一塊,當着一塊內存用完後,將存活的對象複製到另外一塊上面,再把已使用的內存清理掉。
通常虛擬機是將內存分爲一塊較大的Eden空間和兩塊較小的Survivor空間。每次使用?Eden和其中一塊Survivor,回收時,將Eden和Survivor還存後的對象複製到Survivor空間,再清理掉剛纔用到的Survivor和Eden空間。當Survivor內存不足時會用到其餘內存(老年代)進行分配擔保。
缺點:在對象存活率較高時就要進行較多的複製操做,效率會變低,老年代通常不能直接選用這種作法。
標記過程與標記—清除算法相同,而後讓全部存活的對象都像一端移動,而後直接清理掉端邊界之外的內存。適用於老年代整理。
通常根據對象存活週期將對象劃分爲幾塊。Java堆分爲新生代和老年代。新生代通常採用複製算法,而老年代對象存活較高,沒有額外空間對它進行分配擔保,就必須使用標記—清除或標記—整理算法。
是虛擬機在client模式下默認的新生代收集器,是單線程收集器,必須停掉其餘全部工做線程,知道他收集結束。
時Serial收集器的多線程版本。是許多運行在server模式下的虛擬機的首選的新生代收集器。除了Serial收集器外,只有它能與CMS收集器配合工做。
並行多線程的新生代收集器。CMS等收集器的特色是儘量縮短垃圾收集時用戶線程的停頓時間,而Parallel Scavenge收集器的目的是達到一個可控制吞吐量。吞吐量是指CPU用於運行用戶代碼的時間與CPU總消耗的時間的比值
是Serial收集器的老年代版本,單線程收集器。主要是給client模式下的虛擬機使用。在server模式下:一是能夠與Parallel Scavenge收集器配合使用。另外一方面是做爲CMS收集器的後備方案。
是Parallel Scavenge收集器的老年代版本,使用多線程和標記—整理算法。
是一種以獲取最短回收時間爲目標的收集器。基於標記—清除算法實現。運做過程:
其中初始標記和從新標記須要「stop the world」,併發標記和併發清除是和用戶線程一塊兒進行的。
缺點:一、對CPU資源敏感,由於佔用了一部分線程而致使應用程序變慢,總吞吐量會下降。
二、收集器沒法處理浮動垃圾。
3.採用標記—清除算法會產生大量空間碎片。
面向服務端應用的垃圾收集器。優勢以下:
並行併發
分代收集
空間整合
可預測停頓
它將整個Java堆分爲多個大小相等的獨立區域,保留新生代和老年代概念,但他們不是物理隔離,都是一部分Region的集合。G1跟蹤各個Region裏面的垃圾堆積的價值大小,在後臺維護一個優先列表,每次根據容許的手機時間,優先回收價值大的Region。
G1的操做步驟:
須要大量連續的內存空間的Java對象,最典型就是很長的字符串以及數組。
虛擬機給每個對象定義年齡計數器,在Eden代出生並通過一次Minor GC仍存後,並能被Survivor接收,被移到Survivor空間中,年齡加一。在Survivor中每熬過一次GC,年齡就加一。當年齡到必定長度後就進入老年代。
若是在Survivor中的相同年齡全部對象大小的總和大於Survivor空間的一半,年齡大於等於改年齡的對象就會進入老年代。
在Minor GC前虛擬機會先檢查老年代最大可用的連續空間是否大於新生代全部對象的總空間,若是條件成立,那麼Minor GC能夠確保安全。不然虛擬機會查看HandelPromotionFailure設置的值是否容許擔保失敗,若是是,則在檢查老年代最大可用的連續空間是否大於歷次晉升到老年代對象的平均大小,若是大於,嘗試進行一次Minor GC。不然進行一次Full GC
歡迎關注公衆號: