自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

V8 內(nèi)存管理(垃圾回收機(jī)制)

開(kāi)發(fā) 前端
在程序運(yùn)行過(guò)程中肯定會(huì)用到一些數(shù)據(jù),這些數(shù)據(jù)會(huì)放在堆棧中,但是在程序運(yùn)行結(jié)束后,這些數(shù)據(jù)就不會(huì)再被使用了,那些不再使用的數(shù)據(jù)就是垃圾

V8 內(nèi)存管理(垃圾回收機(jī)制)

V8 也會(huì)申請(qǐng)內(nèi)存,申請(qǐng)的內(nèi)存又會(huì)分為堆內(nèi)存和棧內(nèi)存

1.1 棧

  • 棧用于存放 JS 中的基本類(lèi)型和引用類(lèi)型指針
  • 棧的空間是連續(xù)的,增加刪除只需要移動(dòng)指針,操作速度非常快
  • 棧的空間是有限的,當(dāng)棧滿了,就會(huì)拋出一個(gè)錯(cuò)誤
  • 棧一般是在執(zhí)行函數(shù)時(shí)創(chuàng)建的,在函數(shù)執(zhí)行完畢后,棧就會(huì)被銷(xiāo)毀

1.2 堆

  • 堆主要用于存儲(chǔ) JS 中的引用類(lèi)型

1.2.1 堆空間分類(lèi)

1.2.1.1 新生代(new space)

  • 新生代內(nèi)存用于存放一些生命周期比較短的對(duì)象數(shù)據(jù)

1.2.1.2 老生代(old space)

  • 老生代內(nèi)存用于存放一些生命周期比較長(zhǎng)的對(duì)象數(shù)據(jù)
  • 當(dāng)new space的對(duì)象進(jìn)行兩個(gè)周期的垃圾回收后,如果數(shù)據(jù)還存在new space中,則將他們存放到old space中
  • Old Space 使用標(biāo)記清除標(biāo)記整理的方式進(jìn)行垃圾回收

1.2.2 什么是垃圾

  • 在程序運(yùn)行過(guò)程中肯定會(huì)用到一些數(shù)據(jù),這些數(shù)據(jù)會(huì)放在堆棧中,但是在程序運(yùn)行結(jié)束后,這些數(shù)據(jù)就不會(huì)再被使用了,那些不再使用的數(shù)據(jù)就是垃圾

1.2.3 新生代的垃圾回收

  • 新生代內(nèi)存有兩個(gè)區(qū)域,分別是對(duì)象區(qū)域(from) 和 空閑區(qū)域(to)
  • 新生代內(nèi)存使用Scavenger 算法來(lái)管理內(nèi)存,垃圾回收的入口廣度優(yōu)先遍歷 From-Space 中的對(duì)象,從根對(duì)象出發(fā),廣度優(yōu)先遍歷所有能到達(dá)的對(duì)象,把存活的對(duì)象復(fù)制到 To-Space遍歷完成后,清空 From-SpaceFrom-Space 和 To-Space 角色互換
  • 復(fù)制后的對(duì)象在 To-Space 中占用的內(nèi)存空間是連續(xù)的,不會(huì)出現(xiàn)碎片問(wèn)題
  • 這種垃圾回收方式快速而又高效,但是會(huì)造成空間浪費(fèi)(有 To-Space 空閑區(qū)域)
  • 新生代的 GC 比較頻繁
  • 新生代的對(duì)象轉(zhuǎn)移到老生代稱(chēng)為晉升 Promote,判斷晉升的情況有兩種經(jīng)過(guò)一次 GC 還存活的對(duì)象對(duì)象復(fù)制到 To-Space 時(shí),To-Space 的空間達(dá)到一定的限制(超過(guò) 25%)

1.2.4 老生代的垃圾回收

V8 在老生代中的垃圾回收策略采用Mark-Sweep(標(biāo)記清除)和 Mark-Compact(標(biāo)記整理)相結(jié)合

1.2.4.1 Mark-Sweep(標(biāo)記清除)

  • 標(biāo)記清除分為標(biāo)記和清除兩個(gè)階段
  • 在標(biāo)記階段需要遍歷(深度優(yōu)先遍歷)堆中的所有對(duì)象,并標(biāo)記那些活著的對(duì)象,然后進(jìn)入清除階段。在清除階段總,只清除沒(méi)有被標(biāo)記的對(duì)象
  • V8 采取的是黑色和白色來(lái)標(biāo)記數(shù)據(jù),垃圾收集之前,會(huì)把所有的數(shù)據(jù)設(shè)置為白色,用來(lái)標(biāo)記所有的尚未標(biāo)記的對(duì)象,然后會(huì)從 GC 根出發(fā),以深度優(yōu)先的方式把所有的能訪問(wèn)到的數(shù)據(jù)都標(biāo)記為黑色,遍歷結(jié)束后黑色的就是活的數(shù)據(jù),白色的就是可以清理的垃圾數(shù)據(jù)
  • 由于標(biāo)記清除只清除死亡對(duì)象,而死亡對(duì)象在老生代中占用的比例很小,所以效率較高
  • 標(biāo)記清除有一個(gè)問(wèn)題就是進(jìn)行一次標(biāo)記清楚后,內(nèi)存空間往往是不連續(xù)的,會(huì)出現(xiàn)很多的內(nèi)存碎片。如果后續(xù)需要分配一個(gè)需要內(nèi)存空間較多的對(duì)象時(shí),如果所有的內(nèi)存碎片都不夠用,就會(huì)出現(xiàn)內(nèi)存溢出的問(wèn)題

1.2.4.2 Mark-Compact(標(biāo)記整理)

  • 標(biāo)記整理正是為了解決標(biāo)記清除所帶來(lái)的內(nèi)存碎片的問(wèn)題
  • 標(biāo)記整理在標(biāo)記清除的基礎(chǔ)進(jìn)行修改,將其的清除階段變?yōu)榫o縮極端
  • 在整理的過(guò)程中,將活著的對(duì)象向內(nèi)存區(qū)的一段移動(dòng),移動(dòng)完成后直接清理掉邊界外的內(nèi)存
  • 緊縮過(guò)程涉及對(duì)象的移動(dòng),所以效率并不是太好,但是能保證不會(huì)生成內(nèi)存碎片,一般 10 次標(biāo)記清理會(huì)伴隨一次標(biāo)記整理

1.2.5 優(yōu)化

  • 在執(zhí)行垃圾回收算法期間,JS 腳本需要暫停,這種叫 Stop the world(全停頓)
  • 如果回收時(shí)間過(guò)長(zhǎng),會(huì)引起卡頓
  • 性能優(yōu)化把大任務(wù)拆分小任務(wù),分步執(zhí)行,類(lèi)似 fiber將一些任務(wù)放在后臺(tái)執(zhí)行,不占用主線程

JavaScript執(zhí)行 垃圾標(biāo)記、垃圾清理、垃圾整理 JavaScript執(zhí)行
-------------- ---------------->

1.2.5.1 Parallel(并行執(zhí)行)

  • 新生代的垃圾回收采取并行策略提升垃圾回收速度,它會(huì)開(kāi)啟多個(gè)輔助線程來(lái)執(zhí)行新生代的垃圾回收工作

-------輔助線程----->
-------輔助線程----->
-------輔助線程----->
--------- --------------------------->

1.2.5.2 增量標(biāo)記

  • 老生代因?yàn)閷?duì)象又大又多,所以垃圾回收的時(shí)間更長(zhǎng),采用增量標(biāo)記的方式進(jìn)行優(yōu)化
  • 增量標(biāo)記就是把標(biāo)記工作分成多個(gè)階段,每個(gè)階段都只標(biāo)記一部分對(duì)象,和主線程的執(zhí)行穿插進(jìn)行
  • 為了支持增量標(biāo)記,V8 必須可以支持垃圾回收的暫停和恢復(fù),所以采用了黑白灰三色標(biāo)記法黑色表示這個(gè)節(jié)點(diǎn)被 GC 根引用到了,而且該節(jié)點(diǎn)的子節(jié)點(diǎn)都已經(jīng)標(biāo)記完成了灰色表示這個(gè)節(jié)點(diǎn)被 GC 根引用到了,但子節(jié)點(diǎn)還沒(méi)被垃圾回收器標(biāo)記處理,也表明目前正在處理這個(gè)節(jié)點(diǎn)白色表示此節(jié)點(diǎn)還沒(méi)未被垃圾回收器發(fā)現(xiàn),如果在本輪遍歷結(jié)束時(shí)還是白色,那么這塊數(shù)據(jù)就會(huì)被收回
  • 引入了灰色標(biāo)記后,就可以通過(guò)判斷有沒(méi)有灰色節(jié)點(diǎn)來(lái)判斷標(biāo)記是否完成了,如果有灰色節(jié)點(diǎn),下次恢復(fù)的應(yīng)該從灰色節(jié)點(diǎn)繼續(xù)執(zhí)行

---------開(kāi)始標(biāo)記---增量標(biāo)記---增量標(biāo)記---清理---整理----------------->

1.2.5.3 Write-barrier(寫(xiě)屏障)

  • 當(dāng)黑色指向白色節(jié)點(diǎn)的時(shí)候,就會(huì)觸發(fā)寫(xiě)屏障,這個(gè)寫(xiě)屏障會(huì)把白色節(jié)點(diǎn)設(shè)置為灰色

global.a = { name: "a" }
global.a.b = { name: "b1" }
//執(zhí)行標(biāo)記工作
global.a.b = { name: "b2" }
//繼續(xù)執(zhí)行標(biāo)記工作

1.2.5.4 Lazy Sweeping(惰性清理)

  • 當(dāng)增量標(biāo)記完成后,如果內(nèi)存夠用,先不清理,等 JS 代碼執(zhí)行完慢慢清理

1.2.5.5 concurrent(并發(fā)回收)

  • 其實(shí)增量標(biāo)記和惰性清理并沒(méi)有減少暫停的總時(shí)間
  • 并發(fā)回收就是主線程在執(zhí)行過(guò)程中,輔助線程可以在后臺(tái)完成垃圾回收工作
  • 標(biāo)記操作全都由輔助線程完,清理操作由主線程和輔助線程配合完成

----輔助線程標(biāo)記---->      -----清理整理---->
----輔助線程標(biāo)記----> -----清理整理---->
----輔助線程標(biāo)記----> -----清理整理---->
-----------------------------執(zhí)行JS>-----清理整理--->-------------------------

文章出自:??前端餐廳??,如有轉(zhuǎn)載本文請(qǐng)聯(lián)系前端餐廳ReTech今日頭條號(hào)。

github:??https://github.com/zuopf769??

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2020-09-27 07:32:18

V8

2023-06-07 16:00:40

JavaScriptV8語(yǔ)言

2010-09-26 16:42:04

JVM內(nèi)存組成JVM垃圾回收

2009-12-09 17:28:34

PHP垃圾回收機(jī)制

2022-04-29 08:05:06

內(nèi)存堆外GC

2010-09-25 15:33:19

JVM垃圾回收

2017-03-03 09:26:48

PHP垃圾回收機(jī)制

2017-08-17 15:40:08

大數(shù)據(jù)Python垃圾回收機(jī)制

2009-06-23 14:15:00

Java垃圾回收

2024-03-14 09:40:14

2021-11-05 15:23:20

JVM回收算法

2022-04-29 08:00:51

V8垃圾回收

2011-07-04 16:48:56

JAVA垃圾回收機(jī)制GC

2021-05-27 21:47:12

Python垃圾回收

2010-09-25 15:26:12

JVM垃圾回收

2010-09-16 15:10:24

JVM垃圾回收機(jī)制

2011-06-28 12:39:34

Java垃圾回收

2015-06-04 09:38:39

Java垃圾回收機(jī)

2017-06-12 17:38:32

Python垃圾回收引用

2013-04-01 10:07:19

Java內(nèi)存回收機(jī)制
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)