v8大致分爲堆
和棧
,垃圾回收在堆裏進行。node
堆內存分多個模塊:算法
New space瀏覽器
大多數的對象開始都會被分配在這裏,這個區域相對較小可是垃圾回收特別頻繁,該區域被對半分爲兩半(分爲Semi space From 和 Semi space To )ide
Old space優化
新生代中的對象在存活一段時間後就會被轉移到老生代內存區,相對於新生代該內存區域的垃圾回收頻率較低。spa
Large object space操作系統
存放體積超越其餘區域大小的對象,每一個對象都會有本身的內存,垃圾回收不會移動大對象區。線程
Code spacecode
代碼對象會被分配在這裏,惟一擁有執行權限的內存區域。對象
Cells pace
Property cell space
Map space
垃圾回收發生在新生代(New space)和老生代(Old space)中。
根據操做系統不一樣:32位爲0.7G,64位爲1.4G
新生代 | 老生代 | |
---|---|---|
32位系統 | 34M | 700M |
64位系統 | 64M | 1400M |
最新版V14內存爲2G
垃圾回收的算法新生代使用的是Scavenge(新生代互換算法)
。
老生代如今使用的是Mark-Compact(標記整理算法)
,之前使用Mark-Sweep(標記清除算法)
,最古老的是引用計數算法
。
過程:
每次新加入的變量都會放入from,當from中內存佔滿時會開始執行垃圾回收:對from中不用的內存回收,還存在引用的內存會被複制到to中,當此次垃圾回收結束的時候會出現from中爲空,to中留下還存在引用的內存,這時會將from和to交換,最後就是from中留下有引用的內存,to中保持爲空。
由於From和To中各佔一半,而且To始終不會存放,因此會浪費一半的空間。該算法是使用空間換取時間,而老生代比新生代大不少,因此用該算法不合理。
過程:
查看是否有其它的對象在引用該對象,若是沒有則把它清除。
該方法沒法處理對象間的循環引用,容易形成內存泄漏。
在 IE 時代就被拋棄了。
該算法是早先使用的算法,如今已經不被使用
過程:
垃圾回收會在內部構件一個根節點(能夠看做是瀏覽器中的window,node中的gelobal)。首先對老生代中的全部對象進行一次廣度掃描,查找到有對根節點引用的對象時會把它標記,最後將沒有標記的對象垃圾回收。
該算法沒有進行內存的碎片整理,因此之後再須要非陪一個大的對象時會提早觸發垃圾回收,爲解決這個問題就產生了Mark-Compact(標記整理算法)
在標記清除法的基礎上進行了優化:
它在執行垃圾回收的開始把全部被標記內存移動到一塊兒,而後清除未被標記的內存,這樣就解決了大對象存入時連續空間不足的問題。
原先的Mark-Sweep算法會在執行垃圾回收時進行一次廣度掃描,將全部有引用節點標記,這叫作全停頓標記,由於JS是單線程的,因此一次垃圾回收的時間內所有標記對時間的花費會比較大;而如今則是使用增量標記法和三色標記法來進行標記。
將代碼運行和垃圾回收之間的且換變得更加頻繁,而且每次垃圾回收的時候只向下查找一層。
該算法把每一個節點分爲三種狀態:
每次垃圾回收時都進行一次查找,直到引用樹所有標黑後再進行排序-回收。
該模式將每次垃圾回收的標記拆分開插入代碼的運行中,比原先的全停頓標記法體驗更好。(在後續也引入了增量式整理和延遲清理,讓停頓變得更短)
這個判斷很簡單: