如何判定一個對象是否應該回收?以及CMS垃圾回收器和G1收集器的特點

       前文我們聊了垃圾回收的算法,那麼我們現在來看一下,如何判定一個對象時垃圾。舉個例子

Person p = new Person();
p = null;//此時的p是不是已經是一個垃圾

       爲了解決循環引用的問題,java中採取了正向可達的方式,主要是通過Roots對象作爲起點進行搜索,搜索走過的路徑稱爲“引用鏈”,當一個對象到 Roots 沒有任何的引用鏈相連時時,證明此對象不可用,當然被判定爲不可達的對象不一定就會成爲可回收對象。

       被判定爲不可達的對象要成爲可回收對象必須至少經歷兩次標記過程,如果在這兩次標記過程中仍然沒有逃脫成爲可回收對象的可能性,則基本上就真的成爲可回收對象了,能否被回收其實主要還是要看finalize()方法有沒有與引用鏈上的對象關聯,如果在finalize()方法中有關聯則自救成功,改對象不可被回收,反之如果沒有關聯則成功被二次標記成功,就可以稱爲要被回收的垃圾了。

      除了垃圾回收,還有那些工作會造成CPU負載過高(其實這裏給出的是一個場景,就是讓描述一下除了垃圾回收之外,還有那些工作會讓線上CPU佔用到百分之90-100,並且給出排查過程。)。

說一下CMS垃圾回收器和G1收集器的特點,和收集過程。

  1. CMS收集器是一種以獲取最短回收停頓時間爲目標的收集器。基於“標記-清除”算法實現,它的運作過程如下:

    • 初始標記

    • 併發標記

    • 重新標記

    • 併發清除

  • 初始標記、從新標記這兩個步驟仍然需要“stop the world”,初始標記僅僅只是標記一下GC Roots能直接關聯到的對象,熟讀很快,
  • 併發標記階段就是進行GC Roots Tracing,
  • 重新標記階段則是爲了修正併發標記期間因用戶程序繼續運作而導致標記產生表動的那一部分對象的標記記錄,這個階段的停頓時間一般會比初始標記階段稍長點,但遠比並發標記的時間短。
  1. CMS是一款優秀的收集器,主要優點:併發收集、低停頓。

      缺點:
    
    • CMS收集器對CPU資源非常敏感。在併發階段,它雖然不會導致用戶線程停頓,但是會因爲佔用了一部分線程而導致應用程序變慢,總吞吐量會降低。

    • CMS收集器無法處理浮動垃圾,可能會出現“Concurrent Mode Failure(併發模式故障)”失敗而導致Full GC產生。

    • 浮動垃圾:由於CMS併發清理階段用戶線程還在運行着,伴隨着程序運行自然就會有新的垃圾不斷產生,這部分垃圾出現的標記過程之後,CMS無法在當次收集中處理掉它們,只好留待下一次GC中再清理。這些垃圾就是“浮動垃圾”。

    • CMS是一款“標記–清除”算法實現的收集器,容易出現大量空間碎片。當空間碎片過多,將會給大對象分配帶來很大的麻煩,往往會出現老年代還有很大空間剩餘,但是無法找到足夠大的連續空間來分配當前對象,不得不提前觸發一次Full GC。

  2. G1是一款面向服務端應用的垃圾收集器。G1具備如下特點:

    • 並行於併發:G1能充分利用CPU、多核環境下的硬件優勢,使用多個CPU(CPU或者CPU核心)來縮短stop-The-World停頓時間。部分其他收集器原本需要停頓Java線程執行的GC動作,G1收集器仍然可以通過併發的方式讓java程序繼續執行。

    • 分代收集:雖然G1可以不需要其他收集器配合就能獨立管理整個GC堆,但是還是保留了分代的概念。它能夠採用不同的方式去處理新創建的對象和已經存活了一段時間,熬過多次GC的舊對象以獲取更好的收集效果。

    • 空間整合:與CMS的“標記–清理”算法不同,G1從整體來看是基於“標記整理”算法實現的收集器;從局部上來看是基於“複製”算法實現的。

    • 可預測的停頓:這是G1相對於CMS的另一個大優勢,降低停頓時間是G1和CMS共同的關注點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度爲M毫秒的時間片段內,

G1運作步驟:

1、初始標記;2、併發標記;3、最終標記;4、篩選回收

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章