(四)JVM-垃圾收集算法

垃圾回收算法的好壞直接影響到程序運行效率,接下來對幾種常見的回收算法進行介紹。java

標記-清除算法(Mark-Sweep)

該算法是最基礎的收集算法,算法分「標記」和「清除」兩部分。 回收過程是標記出須要全部須要回收的對象,在標記完成後統一回收被標記的對象算法

  • 不足
    1. 標記和清除兩個過程效率並不高。
    2. 標記清理事後會產生大量的不連續的碎片內存,空間內存碎片太多會致使在須要分配大對象時找不到合適的連續內存進行分配。這樣就會提早觸發一次垃圾回收動做。執行過程以下圖:
      標記-清除算法示意圖微信

      複製算法(Copying)

      爲了解決效率問題而出現了複製算法。它將內存劃分爲大小兩塊相等的內存,每次只使用其中一塊,當這塊內存用完了就將還存活的對象複製到另外一塊上,而後把剛剛那塊用完了的內存所有清理,每次都是對半個內存區域進行回收,因此在內存分配時不用考慮內存碎片的問題。
      複製算法示意圖學習

  • 優勢
    算法實現簡單高效
  • 缺點
    將原來將原來可用內存縮小了一半,代價昂貴。.net

    標記-整理算法(Mark-Compact)

    複製算法在存活對象較多的狀況下效率比較低,更關鍵的是不想浪費50%的內存空間,那麼就須要有額外的空間進行分配擔保,已應對100%存活對象的這種極端狀況。所以在老年代使用標記-整理算法。
  • 算法過程
    標記過程和標記-清理算法一致,然後續步驟則先將全部存活的對象移至一端,而後直接清理掉端邊界之外的對象。
    標記-整理算法code

分代收集算法(Generation Collection)

  • 堆內存劃分
    在 Java 中,堆被劃分紅兩個不一樣的區域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被劃分爲三個區域:Eden、From Survivor、To Survivor。
    20160818221750646.jpg
    在默認狀況下
新生代 ( Young ) 與老年代 ( Old ) 的比例的值爲 1:2 
Eden : from : to = 8 : 1 : 1

JVM 每次只會使用 Eden 和其中的一塊 Survivor 區域來爲對象服務,因此不管何時,老是有一塊 Survivor 區域是空閒着的。
所以,新生代實際可用的內存空間爲 9/10 ( 即90% )的新生代空間。
注 堆內存劃分 摘自: java堆內存劃分,詳情點連接查看對象

分代收集算法根據堆中對象生存週期的不一樣,對各個區域採用不一樣的蒐集算法。在新生代中每次蒐集都有大量的對象死去,少許的對象存活,因此在這個區域採用「複製算法」,而在老年代,對象存活率高,沒有額外的內存分配擔保,那麼它必須使用「標記-整理「或」標記-清除「算法。blog

關注微信公衆號一塊兒讀書學習交流
CodeBooker內存

相關文章
相關標籤/搜索