回覆列表
  • 1 # 程式設計師小陶

    垃圾回收演算法只是一種策略,虛擬機器不同的配置會採用不同的演算法組合來回收新生代和來年代的。

    而記憶體分佈和策略無關。一般的新建立的物件進入新生代,大物件直接進入老年代,還有根據動態年齡進入老年代等等這些都是虛擬機器的引數決定的。可以修改,自定義。

  • 2 # 淺析架構

    首先得知道垃圾回收演算法有哪些?

    垃圾判定方法

    再說垃圾回收演算法有什麼之前,我們看看是怎麼判斷哪些物件是可以回收的,一般有兩種方法:

    1、引用計數,該方法有迴圈引用問題

    引用計數就是使用一次,引用次數加1,釋放減1,當為0的時候就回收了。迴圈引用問題,就是A引用B,B引用A,這樣就永遠不會釋放了。

    2、可達性分析(JVM採用該方法)

    可達性分析是從GC Roots物件進行搜尋,不能搜尋到的就可以回收

    GC Roots物件:棧(虛擬機器棧和本地棧)中引用的物件;方法區(靜態屬性)中引用的物件

    垃圾回收演算法

    明白了怎麼來定義垃圾了,就需要明白有哪些垃圾回收演算法:

    1、標記--清除(Mark-Sweep)

    該演算法分為兩部分,先把記憶體中物件中的可回收的物件標記出來,然後清理掉。但是該演算法存在一個問題,就是記憶體碎片。如圖中畫紅色叉的地方是可以回收的,沒有劃紅叉的地方是使用的記憶體,如果回收之後,都是小記憶體區域,想分配一段連續的記憶體就沒地方了

    2、複製演算法

    複製演算法就是解決了標記清除演算法了記憶體碎片問題。將記憶體劃分為大小相等的兩塊,每次用一塊,一塊用完了,就把存活的物件複製到另一塊上面,然後把不使用的物件清除。但是代價較高,只能使用一半記憶體

    3、標記整理演算法

    標記整理也是解決了記憶體碎片問題,標記清除之間清除了物件,而標記整理是把所有存活物件都移動到一起,再清除不再使用物件。這樣解決了記憶體碎片問題,而且解決了只使用一半記憶體的問題,但是物件移動效率比較低。

    4、分代收集演算法

    分代收集就是整合了前3種演算法。把記憶體分為新生代和老年代,這樣針對不同的年代使用不同的演算法。新生代中,大量物件需要清除,可以選擇複製演算法,只需要複製少量物件;老年代存活物件比較多,可以使用標記清理演算法或標記整理演算法。

    Java堆記憶體

    JVM選擇的就是分代收集演算法,從而決定了JVM記憶體的分成不同的代來使用不同的演算法。

    新生代分為適合複製演算法,因為物件存活率不高。複製演算法意味著要浪費一定的記憶體,Java的新生代分為Eden和Survivor區,Survivor區又分為from和to區。

    物件分配的時候都會進入Eden區,當Eden去空間不足的時候就會發起一次Minor GC,把存活物件移動到Survivor的from區(from區空間不夠,進去Old區,to區的物件也會移動到from區),Eden的其他物件可以被清除,這時候from和to區的職責互換,下次就是Eden的存活物件移動到to區,from區的物件也會移動到to區。這樣永遠只有from和to區其中一塊記憶體空閒。

    老年代(Old區),物件進行16次Minor GC才會從新生代進入老年代,老年代只有在Major GC才會進行清理,因為存活物件比較多,可以使用標記清理演算法或標記整理演算法。Major GC會發生“Stop-The-World”,STW時間越長,對系統影響也就越大。

    一個物件除了進行16次(次數可以動態設定)Minor GC才會從新生代進入老年代,大物件也會直接進行老年代

  • 中秋節和大豐收的關聯?
  • 要是杜蘭特來到火箭隊,火箭隊能奪得總冠軍嗎?