Js GC原理:
找出那些再也不繼續使用的變量,而後釋放其所佔用的內存,垃圾回收器會按照固定的時間間隔週期性地執行這一操做瀏覽器
Js GC 策略:
JavaScript 內存分配:
- 在定義變量時就完成了內存分配,還能夠經過函數調用分配內存,使用值的過程其實是對分配內存進行讀取與寫入的操做
標記清除法:
- 標記方式:特殊位的反轉、維護一個列表
- 原理:垃圾收集器在運行的時候會給存儲在內存中的全部變量都加上標記,而後它會去掉環境中的變量已經被環境中變量被標記爲引用的變量,在此以後再被標記的變量將被視爲準備刪除的變量。最後垃圾回收器清除標記的變量,回收它們所佔用的內存空間
- 目前主流瀏覽器都是使用標記清除式的垃圾回收策略,只不過收集的間隔有所不一樣
引用計數:
- 原理:每次引用加一,被釋放時減一,當這個值的引用次數變成 0 時,就能夠將其內存空間回收
- 缺點:循環引用(obj1 和 obj2 經過各自的屬性相互引用,也就是說,這兩個對象的引用次數都是 2)
IE兼容問題
- 在 IE9 以前,IE 中有一部分對象並非原生 JavaScript 對象。例如,BOM 和 DOM 中的對象就是 C++ 實現的 COM 對象,而 COM 對象的垃圾收集機制採用的是引用計數策略。所以,即便 IE 中的 JavaScript 引擎使用標記清除策略實現,可是 JS 訪問的 COM 對象依然是基於引用計數策略的。能夠在 IE 中涉及到 COM 對象,就會存在循環引用的問題
- 解決:將變量設置爲 null
V8內存機制
- V8 引擎會限制 JavaScript 所能使用的內存大小
-
性能問題:(運行時間間隔)函數
-
V8 的堆構成指針
- 新生區:大多數對象被分配在這裏。新生區是一個很小的區域,垃圾回收在這個區域很是頻繁,與其餘區域相獨立。
- 老生指針區:這裏包含大多數可能存在指向其餘對象的指針的對象。大多數在新生區存活一段時間以後的對象都會被挪到這裏。
- 大對象區:這裏存放體積超越其餘區大小的對象。每一個對象有本身 map 產生的內存。垃圾回收器從不移動大對象。
-代碼區:代碼對象,也就是包含 JIT 以後指令的對象,會被分配到這裏。這是惟一擁有執行權限的內存區(不過若是代碼對象因過大而放在大對象區,則該大對象所對應的內存也是可執行的。譯註:可是大對象內存區自己不是可執行的內存區)。
-Cell 區、屬性 Cell 區、Map 區:這些區域存放 Cell、屬性 Cell 和 Map,每一個區域由於都是存放相同大小的元素,所以內存結構很簡單
-
分代回收code
- 緣由:絕大多數對象的生存期很短,只有某些對象的生存期較長
- 過程:
一、對象起初會被分配在新生區(一般很小,只有 1-8 MB)在新生區的內存分配很是容易:咱們只需保有一個指向內存區的指針,不斷根據新對象的大小對其進行遞增便可。當該指針達到了新生區的末尾,就會有一次清理(小週期),清理掉新生區中不活躍的死對象。對象
二、活躍超過 2 個小週期的對象,則需將其移動至老生區老生區在標記-清除或標記-緊縮(大週期)的過程當中進行回收。大週期進行的並不頻繁。一次大週期一般是在移動足夠多的對象至老生區後纔會發生。至於足夠多究竟是多少,則根據老生區自身的大小和程序的動向來定。生命週期