第六章 JVM垃圾收集器(2)

来源:http://www.cnblogs.com/java-zhao/archive/2016/02/06/5183999.html
-Advertisement-
Play Games

上一章記錄了幾種常見的垃圾收集器,見《第五章 JVM垃圾收集器(1)》 1、G1 說明: 從上圖來看,G1與CMS相比,僅在最後的"篩選回收"部分不同(CMS是併發清除),實際上G1回收器的整個堆記憶體的劃分都與其他收集器不同。 CMS需要配合ParNew,G1可單獨回收整個空間 原理: G1收集器將


上一章記錄了幾種常見的垃圾收集器,見《第五章 JVM垃圾收集器(1)

 

1、G1

說明:

  • 從上圖來看,G1與CMS相比,僅在最後的"篩選回收"部分不同(CMS是併發清除),實際上G1回收器的整個堆記憶體的劃分都與其他收集器不同。
  • CMS需要配合ParNew,G1可單獨回收整個空間

原理:

  • G1收集器將整個堆劃分為多個大小相等的Region
  • G1跟蹤各個region裡面的垃圾堆積的價值(回收後所獲得的空間大小以及回收所需時間長短的經驗值),在後臺維護一張優先列表,每次根據允許的收集時間,優先回收價值最大的region,這種思路:在指定的時間內,掃描部分最有價值的region(而不是掃描整個堆記憶體),並回收,做到儘可能的在有限的時間內獲取儘可能高的收集效率。

運作流程:

  • 初始標記:標記出所有與根節點直接關聯引用對象。需要STW
  • 併發標記:遍歷之前標記到的關聯節點,繼續向下標記所有存活節點。
    • 在此期間所有變化引用關係的對象,都會被記錄在Remember Set Logs中
  • 最終標記:標記在併發標記期間,新產生的垃圾。需要STW
  • 篩選回收:根據用戶指定的期望回收時間回收價值較大的對象(看"原理"第二條)。需要STW

優點:

  • 停頓時間可以預測:我們指定時間,在指定時間內只回收部分價值最大的空間,而CMS需要掃描整個年老代,無法預測停頓時間
  • 無記憶體碎片:垃圾回收後會整合空間,CMS採用"標記-清理"演算法,存在記憶體碎片
  • 篩選回收階段:
    • 由於只回收部分region,所以STW時間我們可控,所以不需要與用戶線程併發爭搶CPU資源,而CMS併發清理需要占據一部分的CPU,會降低吞吐量。
    • 由於STW,所以不會產生"浮動垃圾"(即CMS在併發清理階段產生的無法回收的垃圾)

適用範圍:

  • 追求STW短:若ParNew/CMS用的挺好,就用這個;若不符合,用G1
  • 追求吞吐量:用Parallel Scavenge/Parallel Old,而G1在吞吐量方面沒有優勢

 

2、幾點註意

問題1、G1以外的其他收集器在回收垃圾的時候:要不只是掃描年輕代,要不只是掃描年老代。在年輕代的回收過程中,如果舊生代中的對象引用了年輕代的對象,那麼我們只掃描年輕代就不行了,但是由於年老代一般而言是年輕代的3倍大小,如果年輕代、年老代一起去掃描的話,效率會急劇下降,這個問題怎麼處理?

:JVM採用remember set來做的這個事兒,當發現一個引用對象被賦值時,JVM發出一個write barrier指令來暫時中斷寫操作,檢查被賦值的引用對象是不是處於年老代,且其引用的對象是不是處於新生代(即是不是年老代對象引用了年輕代對象),如果是,將相關引用信息記錄到remember set。之後的掃描,我們會從根集合+remember set向下進行掃描。(也就是說真正的根集合,是JVM定義的根集合+remember set

 

問題2、G1收集器為了做到GC時間可預測,採用掃描部分價值最大的region來實現,那麼如果這部分region中的對象被其他region中的對象所引用,那麼僅掃描前者可能就不行了,但是如果掃描全部region的話,又無法做到GC時間可預測,效率會大大下降,怎麼辦?

:G1同理,為每一個region分配一個remember set,當發現一個引用對象被賦值時,JVM發出一個write barrier指令來暫時中斷寫操作,檢查被賦值的引用對象與其引用的對象是不是處於不同的region(eg.a=b;檢查a與b是不是在不同的region),如果是,將相關引用信息記錄到當前region的remember set。之後的掃描,我們會從根集合+remember set向下進行掃描。

 

問題3、CMS與G1在併發標記的時候若發部分引用對象的引用關係發生了變化,怎麼處理才能讓重新標記的時候僅僅掃描出這些變化?

:在併發標記期間,對象的引用關係若發生了變化,這些相關的記錄就會記錄到remember set logs在重新標記階段,將該logs的信息加入到remember set中去,然後再從remember set去向下trace節點。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前段時間,項目中有個需求,需要將linux和windows的時間進行同步,網上也有很多類似時鐘同步的帖子,大致類似;不過本次的linux的機器有點特殊,沒有service命令,而且要求在另一臺suse的linux機器上通過腳本連接到目的linux機器進行時鐘同步。起先我也被困擾的很久,不過辦法都是人
  • 類的繼承,是在父類中存在可繼承的成員A,而在子類中不存在同名成員,這樣該成員會被繼承到子類,當子類對象訪問該成員時,實際訪問的是父類的對應成員。類的重寫,是在父類中存在可繼承的成員A,而在子類中存在同名成員,這樣該成員會被子類重寫,當子類對象訪問該成員時,實際訪問的是子類的成員。所以二者的區別就是,
  • 在節前的最後一天,解決了打包過程中遇到的所有問題,可以成功運行了!真是個好彩頭,希望新的一年一切順利! 以下是在使用cx_freeze過程中遇到的問題及解決辦法(Win7) 問題描述:運行exe,啟動無數個主程式,導致系統無法使用 原因:在程式中使用了multiprocessing的包 解決辦法:在
  • package CommonClassPart; import java.io.File; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class Common
  • /*漢諾塔的玩法: * 游戲的規則:將A柱上的盤子移動到C柱上,大盤必須在小盤之上。 * 1 當A柱上只有一個盤子的時候,直接移動到C柱上; * 2 當A柱上有兩個盤子的時候, * 將A柱上的1盤(從上到下編號)移動到B柱, * 將A柱上的2盤移動到C柱, * 將B柱上的1盤移動到C柱; * (將A
  • 本文實例講述了PHP限制HTML內容中圖片必須是本站的方法。分享給大家供大家參考。具體實現方法如下: 1. PHP代碼如下: <?php $dom = new DOMDocument; $dom->loadHTML(file_get_contents('input.html')); $xpath =
  • java magic翻譯系列文章,java小伙伴不知道的奇妙世界
  • package CollectionPart; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class CollectionSort { public static v
一周排行
    -Advertisement-
    Play Games
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...
  • 1. JUnit 最佳實踐指南 原文: https://howtodoinjava.com/best-practices/unit-testing-best-practices-junit-reference-guide/ 我假設您瞭解 JUnit 的基礎知識。 如果您沒有基礎知識,請首先閱讀(已針 ...