Document
2020-09-29
V8引擎
認識V8:
- V8是一款主流的JS執行引擎
- V8采用即時編譯 所以速度很快
- V8有內存設限 32位是不超過800MB 64位是不超過1.5GB
- 值類型的數據存在棧里由系統回收 一般我們說的垃圾回收都是回收堆里的 也就是復雜數據類型
V8回收策略:
- V8采用分代回收的思想
- 內存分為新生代存儲區、老生代存儲區 兩種
- 為了區分新生代老生代 V8內存空間一分為二 左側存儲新生代 右側存儲老生代
- 針對不同種類對象采用不同的算法 以達到最高效的處理
V8常用的GC算法:
- 分代回收 新生代和老生代
- 空間復制 From空間復制到To
- 標記清除
- 標記整理
- 標記增量
新生代對象的垃圾回收:
- 小空間用於存儲新生代對象 64位最大32MB 32位最大16MB
- 新生代對象指的是存活時間較短的對象 例如某函數局部作用域中的一些變量
- 回收過程采用復制算法+標記整理
- 將新生代內存也分成兩個大小相等的空間
- 使用空間為From,空閑空間為To
- 活動對象存儲於From空間中 To一直是空閑的
- 當From空間應用到一定程度之后 觸發GC操作
- 標記整理后將活動對象拷貝到To空間中
- From空間全部釋放 然后與To空間交換就完成了垃圾回收
新生代對象回收細節:
- 拷貝過程中有可能出現晉升
- 晉升:指的是將新生代對象移動至老生代進行存儲
- 一般 一輪GC后 還存活的新生代對象需要晉升 考慮到並不是存活時間短
- 如果To空間的使用率超過25% 那么這些對象也需要晉升
- 因為如果To空間使用率過大 當To變成From后 有可能沒有多少剩余內存留給新進來的數據了
老生代對象的垃圾回收:
- 大空間用於存儲老生代對象 64位最大1.4GB 32位最大700MB
- 老生代對象指的是存活時間較長的對象 例如全局下的一些變量 或者是閉包中的變量
- 回收過程采用 標記清除+標記整理+標記增量算法
- 首先 主要是 使用標記清除完成垃圾空間的回收
- 當有新生代晉升 且老生代內存塊不足以存儲晉升的數據時 觸發標記整理 整理碎片化的內存
- 采用增量標記進行效率優化
- 增量標記:標記過程會阻塞代碼執行 所以將整個標記過程分成很多次交替的插在執行過程中去標記
總結對比:
- 新生代區域的垃圾回收是 使用空間換時間 因為每時每刻都有一般空閑空間的存在 通過復制清除的方式快速清理垃圾
- 老生代區域垃圾回收不適合復制算法 因為老生代的內存很大 且數據多 復制浪費時間 浪費內存