日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入理解G1垃圾收集器

發布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解G1垃圾收集器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

G1(Garbage First)垃圾收集器是當今垃圾回收技術最前沿的成果之一。早在JDK7就已加入JVM的收集器大家庭中,成為HotSpot重點發展的垃圾回收技術,JDK9 默認就是使用的G1垃圾收集器。

不同于其他的分代回收算法,G1最大的特點是引入分區的思路,弱化了分代的概念,合理利用垃圾收集各個周期的資源,解決了其他收集器甚至CMS的眾多缺陷。每塊區域既有可能屬于O區、也有可能是Y區,且每類區域空間可以是不連續的(對比CMS的O區和Y區都必須是連續的)。

G1有三個明顯特點:1、壓縮空間強,避免碎片\color{red}{壓縮空間強,避免碎片} 2、空間使用更靈活 3、GC停頓周期更可控,避免雪崩\color{red}{GC停頓周期更可控, 避免雪崩}GC

G1其實是Garbage First的意思,垃圾優先? 不是,是優先處理那些垃圾多的內存塊的意思。

一般的垃圾回收器把內存分成三類: Eden(E), Suvivor(S)和Old(O)。

G1雖然也把內存分成了這三大類,但是在G1里面這三大類不是涇渭分明的三大塊內存,G1把內存劃分成很多小塊, 每個小塊會被標記為E/S/O中的一個,可以前面一個是Eden后面一個就變成Survivor了。

這么做給G1帶來了很大的好處,由于把三塊內存變成了幾百塊內存,內存塊的粒度變小了,從而可以垃圾回收工作更徹底的并行化

G1的并行收集做得特別好,我們第一次聽到并行收集應該是CMS(Concurrent Mark & Sweep)垃圾回收算法, 但是CMS的并行收集也只是在收集老年代能夠起效,而在回收年輕代的時候CMS是要暫停整個應用的(Stop-the-world)。而G1整個收集全程幾乎都是并行的

它回收的大致過程是這樣的:

  • 在垃圾回收的最開始有個短暫的時間段(Inital Mark)會停止應用(stop-the-world)
  • 然后應用繼續運用,同時G1開始Concurrent Mark
  • 再次停止應用,來Final Mark(stop-the-world)
  • 最后感覺Garbage First的原則,選擇一些內存塊進行回收
  • G1的另一個顯著特點他能夠讓用戶設置應用的暫停時間,為什么G1能做到這一點呢?

    也許你已經注意到了,G1回收的第4步,它是“選擇一些內存塊”,而不是整代內存來回收,這是G1跟其它GC非常不同的一點,其它GC每次回收都會回收整個Generation的內存(Eden, Old), 而回收內存所需的時間就取決于內存的大小,以及實際垃圾的多少,所以垃圾回收時間是不可控的;而G1每次并不會回收整代內存,到底回收多少內存就看用戶配置的暫停時間\color{red}{到底回收多少內存就看用戶配置的暫停時間},配置的時間短就少回收點,配置的時間長就多回收點 ,伸縮自如。

    由于內存被分成了很多小塊,又帶來了另外好處,由于內存塊比較小,進行內存壓縮整理的代價都比較小,相比其它GC算法,可以有效的規避內存碎片的問題。

    記憶集Remembered Set:

    G1相關概念非常多,有一個重點就是Remembered Set,用于記錄和維護region之間對象的引用關系。為什么需要這么做呢?試想,新生代GC是復制算法,也就是說,類似對象 從Eden或者Survivor到to區域的“移動”,其實是“復制”,本質上是一個新的對象。在這個過程中,需要必須保證老年代到新生代的跨區引用仍然有效。比如card table是remembered set的一種實現。下面的示意圖說明了相關設 計。

    G1 的缺點:

    G1 需要記憶集 (具體來說是卡表,Remembered Set)來記錄新生代和老年代之間的引用關系,這種數據結構在 G1 中需要占用大量的內存,可能達到整個堆內存容量的 20% 甚至更多。而且 G1 中維護記憶集的成本較高,帶來了更高的執行負載,影響效率。

    G1對比CMS的區別在:

  • G1在壓縮空間方面有優勢
  • G1通過將內存空間分成區域(Region)的方式避免內存碎片問題
  • Eden,Survivor,Old區不再固定、在內存使用效率上來說更靈活
  • G1可以通過設置預期停頓時間(Pause Time)來控制垃圾收集時間避免應用雪崩現象,可駕馭度,G1 是可以設定GC 暫停的 target 時間的,根據預測模型選取性價比收益更高,且一定數目的 Region 作為 CSet,能回收多少便是多少。
  • G1在回收內存后會馬上同時做,合并空閑內存的工作、而CMS默認是在STW(stop the world)的時候做
  • G1會在Young GC中使用、而CMS只能在O區使用
  • SATB 算法在 remark 階段延遲極低以及借助 RSet 的實現可以不做全堆掃描(G1 對大堆更友好)以外,最重要的是可駕馭度
  • 目前CMS還是默認首選的GC策略、可能在以下場景下G1更適合:

  • 服務端多核CPU、JVM內存占用較大的應用(至少大于4G)
  • 應用在運行過程中產生大量內存碎片、需要經常壓縮空間
  • 想要更可控、可預期的GC停頓周期:防止高并發應用雪崩現象
  • G1 的 JVM調優

    1、region太小不合適,會令你在分配大對象時更難找到連續空間
    -XX:G1HeapRegionSize=<N, 例如16>M
    2、老年代回收,則是依靠Mixed GC,指定觸發閾值,并且設定最多被包含在一次Mixed GC中的region比例
    –XX:G1MixedGCLiveThresholdPercent –XX:G1OldCSetRegionThresholdPercent
    3、在垃圾收集過程中,G1會把新創建的字符串對象放入隊列中,然后在Young GC之后,并發地(不會STW)將內部數據 (char數組,JDK 9以后是byte數組)一致的字符串進行排重,也就是將其引用同一個數組。你可以使用下面參數激活
    -XX:+UseStringDeduplication
    4、G1只有在發生Full GC時才進行類型卸載,但這顯然不是我們想要的。你可以加上下面的參數,在并發標記階段結束后,JVM即進行類型卸載
    -XX:+ClassUnloadingWithConcurrentMark
    5、建議開啟選項下面的選項進行并行引用處理
    -XX:+ParallelRefProcEnabled

    總結

    G1是一款壓縮型的收集器.G1通過有效的壓縮完全避免了對細微空閑內存空間的分配,不用依賴于regions,這不僅大大簡化了收集器,而且還消除了潛在的內存碎片問題。除壓縮以外,G1的垃圾收集停頓也比CMS容易估計,也允許用戶自定義所希望的停頓參數(pause targets)

    總結

    以上是生活随笔為你收集整理的深入理解G1垃圾收集器的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。