【007】v8垃圾回收機制

前言

這是接着上一篇垃圾回收機制博客的博客。主要講講v8引擎新生代老生代的回收算法。

內存大小

32位系統

  • 新生代:16MB
  • 老生代:0.7G

64位系統

  • 新生代:32MB
  • 老生代:1.4G

一、新生代回收算法

新生代採用Scavenge垃圾回收算法,Scavenge(清除),在算法實現時主要採用Cheney算法(以空間換時間)。新生代的內存中分爲兩個半空間,from和to。其中from是用來使用分配空間的,to是空閒的。

算法步驟

  1. from空間中分配了一些對象,通過GC機制將無法訪問的的對象和能訪問的活躍對象區分開。
  2. 將活躍的對象從from空間複製到to空間
  3. 再將from空間的所有對象全部清除。
  4. 此時交換from和to空間,讓活着的對象任然保存在from空間中,to空間空閒。值得注意的是from和to只是名稱交換,但是空間大小沒有交換

注意點(晉升)

新生代到老生代的過程就是晉升。

  1. 如果一個對象經過一次from-to的的Cheney算法(,在第二次Cheney的時候還存活那麼會直接放到老生代中。總結來說,如果一個對象是第二次經歷從From空間複製到To空間,那麼這個對象會被移動到老生代中。
  2. 從from半空間複製到to半空間的時候,如果這個時候的可用to的空間不足原來的75%,那麼這個對象也會晉升到老生代。
    • 原因:設置75%的閾值是因爲to空間的大小在經歷了新生代的清除垃圾回收算法後面會變成from空間的大小,然而from空間會存放很多對象

二、老生代算法

1.標記清除法

老生代採用標記清除法,遍歷堆內存中所有對象,標記可訪問的對象,清除不可訪問的對象。新生代Scavenge算法複製活着的對象,老生代標記-清除法清除死去的對象。這是考慮到新生代中活着的對象少,老生代中死去的對象少。可以這樣簡便記憶新活少,老活多

2.標記整理法Mark-Compact

由來

Mark-Compact的產生是爲了解決標記清除法的問題,什麼爲問題呢?
假如下圖是經歷過一次標記清除的內存模擬圖,ACE都是活着的對象。
在這裏插入圖片描述
標記清除法清除掉死掉的對象後出現了內存空間不連續的問題。如果有一個對象需要較大的內存但是由於剩餘的碎片空間不足以完成此次分配,就會提前觸發垃圾回收,而這次回收是不必要的。因此就出現了標記整理法。

算法

  1. 遍歷所有對象,將活着的對象標記。
  2. 然後將活着的對象往另一邊挪動,緊挨着一起,如圖ACE
    在這裏插入圖片描述
  3. 然後刪除左邊所有的對象。

3.兩種方法結合

總的來說兩種方法各有長處短處,一般採用標記清除法因爲他不需要向一側挪動活着的對象。當內存較大碎片空間不足以完成分配的時候就會使用標記整理法。

推薦閱讀

算法具體的僞代碼實現,一篇文章推薦閱讀
V8 JavaScript引擎研究(三)垃圾回收器的實現

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