成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript 內(nèi)存管理及 V8 優(yōu)化

wenhai.he / 3171人閱讀

摘要:內(nèi)存管理具有垃圾自動(dòng)回收機(jī)制簡(jiǎn)稱。標(biāo)記清除標(biāo)記清除是目前大部分引擎使用的判斷方式,通過標(biāo)記變量的狀態(tài)來確定是否可被回收。被標(biāo)記,進(jìn)入環(huán)境被標(biāo)記,進(jìn)入環(huán)境執(zhí)行完畢之后被標(biāo)記,離開環(huán)境引用計(jì)數(shù)引擎維護(hù)一張引用表,保存內(nèi)存中所有的資源的引用次數(shù)。

JavaScript 內(nèi)存管理

JavaScript 具有垃圾自動(dòng)回收機(jī)制(Garbage Collection)簡(jiǎn)稱 GC。垃圾回收機(jī)制會(huì)中斷整個(gè)代碼執(zhí)行,釋放不可能再被使用的變量,釋放內(nèi)存,這個(gè)工作機(jī)制是周期性的,我們會(huì)在下文詳細(xì)探討。

可釋放對(duì)象
function fn1() {
  var obj1 = { name: "xiaomuchen", age: "20" }
}
function fn2() {
  var obj2 = { name: "xiaomuchen", age: "20" }
  return obj2
}
var a = fn1()
var b = fn2()
console.log(a, b) // undefined, {name: "xiaomuchen", age: "20"}

我們對(duì)比上面兩個(gè)函數(shù),fn1 在函數(shù)內(nèi)聲明變量 obj1 并且賦值,在函數(shù)執(zhí)行后這個(gè)變量便不可再訪問了,fn2 在最后把函數(shù)內(nèi)的變量 obj2 返回到全局變量 b,所以 { name: "xiaomuchen", age: "20" } 這個(gè)對(duì)象(或者說 obj2)依然可被訪問。

JavaScript 回收機(jī)制通過判斷變量是否可被訪問,來決定回收哪些變量。

標(biāo)記清除和引用計(jì)數(shù)

那么 JavaScript 是如何判斷變量是否可被訪問?這就要提到標(biāo)記清除和引用計(jì)數(shù)。

標(biāo)記清除:標(biāo)記清除是目前大部分 JavaScript 引擎使用的判斷方式,通過標(biāo)記變量的狀態(tài)來確定是否可被回收。當(dāng)變量在環(huán)境中被聲明時(shí)標(biāo)記進(jìn)入環(huán)境,理論上永遠(yuǎn)不要釋放進(jìn)入環(huán)境的變量,因?yàn)樗梢栽诃h(huán)境中的任何位置、任何時(shí)刻被訪問。當(dāng)環(huán)境被銷毀(如函數(shù)執(zhí)行完),則變量被標(biāo)記離開環(huán)境等待回收。

function fn(){
  var a = { count: 10 } // 被標(biāo)記,進(jìn)入環(huán)境 
  var b = { count: 20 } // 被標(biāo)記,進(jìn)入環(huán)境
}
fn(); // 執(zhí)行完畢之后 b 被標(biāo)記,離開環(huán)境

引用計(jì)數(shù):JavaScript 引擎維護(hù)一張引用表,保存內(nèi)存中所有的資源的引用次數(shù)。資源被引用一次則引用 +1,資源被去掉引用或者退出變量的函數(shù)作用域時(shí),則引用 -1,當(dāng)資源的引用次數(shù)為0時(shí),說明無法訪問這個(gè)值,則等待回收。
(注:引用計(jì)數(shù)從 1 到 0 這個(gè)過程可能不執(zhí)行,而是直接標(biāo)記可被回收,不再進(jìn)行加減運(yùn)算節(jié)約開銷)

function fn(){
  var a = { count: 10 } // 資源 { count: 10 } 被引用次數(shù)為 1
  a = { count: 20 } // 資源 { count: 20 } 被引用次數(shù)為 1,資源 { count: 10 } 被引用次數(shù)為 0,等待回收
  // do someThing
}
fn(); // 資源 { count: 20 } 被釋放

但是引用計(jì)數(shù)存在一種循環(huán)引用的情況,如下例子,兩個(gè)對(duì)象之間相互引用,在離開環(huán)境后對(duì)象不可訪問,但由于對(duì)象的引用次數(shù)為 1,則導(dǎo)致不會(huì)被回收。這個(gè)例子來自《JavaScript 高級(jí)程序設(shè)計(jì)》,但我思考良久,如果引用計(jì)數(shù)把 a.param 也作為一個(gè)變量來計(jì)數(shù),那么就沒有這個(gè)問題了,引用計(jì)數(shù)實(shí)現(xiàn)的方式不同,產(chǎn)生的結(jié)果也不一樣。

function fn(){
  var a = { count: 10 }
  var b = { count: 20 }
  a.param = b // b 的引用次數(shù)為 2
  b.param = a // a 的引用次數(shù)為 2
}
fn(); // a、b 的引用次數(shù)為 1
GC 的缺陷、分代回收和增量 GC

和其他語言一樣 GC 會(huì)中斷代碼執(zhí)行,停止其他操作。因?yàn)橐闅v所有對(duì)象,回收所有不可訪問對(duì)象,這個(gè)操作的耗時(shí)可能有 100ms 以上。在 V8 引擎新版本中引入了兩種優(yōu)化方法:1. 分代回收(Generation GC),2. 增量 GC(increment GC)

分代回收:目的是通過對(duì)象的使用頻率、存在時(shí)長(zhǎng)區(qū)分新生代與老生代對(duì)象。多回收新生代區(qū)(young generation),少回收老生代區(qū)(tenured generation),減少每次需遍歷的對(duì)象,從而減少每次GC的耗時(shí)

增量 GC:把需要長(zhǎng)耗時(shí)的遍歷、回收操作拆分運(yùn)行,減少中斷時(shí)間,但是會(huì)增大上下文切換開銷

Node.js 中的 GC 表現(xiàn)

當(dāng)我們用 Node.js 搭建一個(gè)穩(wěn)定的服務(wù)時(shí),就需要考慮服務(wù)器內(nèi)存的開銷,下面一個(gè) Node.js 內(nèi)存回收?qǐng)?zhí)行的例子:

執(zhí)行代碼node --trace_gc --trace_gc_verbose test.js跟蹤一個(gè)網(wǎng)絡(luò)服務(wù)的 GC。

[41204:0x102001c00] Memory reducer: call rate 0.056, low alloc, foreground
[41204:0x102001c00] Memory reducer: started GC #1
[41204:0x102001c00] Heap growing factor 1.1 based on mu=0.970, speed_ratio=42956 (gc=675253, mutator=16)
[41204:0x102001c00] Grow: old size: 21382 KB, new limit: 33604 KB (1.1)
[41204:0x102001c00] Memory reducer: finished GC #1 (will do more)
[41204:0x102001c00]   156410 ms: Mark-sweep 27.7 (50.0) -> 21.0 (30.0) MB, 12.4 / 0.0 ms (+ 20.4 ms in 7 steps since start of marking, biggest step 4.8 ms) [Incremental marking task: finalize incremental marking] [GC in old space requested].
[41204:0x102001c00] Memory allocator,   used:  30756 KB, available: 1435612 KB
[41204:0x102001c00] New space,          used:    169 KB, available:    838 KB, committed:   1024 KB
[41204:0x102001c00] Old space,          used:  16662 KB, available:   2417 KB, committed:  19412 KB
[41204:0x102001c00] Code space,         used:   4078 KB, available:    178 KB, committed:   5120 KB
[41204:0x102001c00] Map space,          used:    642 KB, available:      0 KB, committed:   2128 KB
[41204:0x102001c00] Large object space, used:      0 KB, available: 1434571 KB, committed:      0 KB
[41204:0x102001c00] All spaces,         used:  21552 KB, available: 1438005 KB, committed:  27684 KB
[41204:0x102001c00] External memory reported:   1026 KB
[41204:0x102001c00] Total time spent in GC  : 158.6 ms
[41204:0x102001c00] Memory reducer: call rate 0.003, low alloc, foreground

首先我們可以看到 Node.js 區(qū)分 New space、Old space 等來劃分檢索空間。而提示(+ 20.4 ms in 7 steps since start of marking, biggest step 4.8 ms) 告訴我們這個(gè)標(biāo)記的步驟分 7 步進(jìn)行,耗時(shí)最長(zhǎng)的一次時(shí) 4.8ms。這使 JavaScript 可以很好的支持開發(fā)高實(shí)時(shí)應(yīng)用,原文。

總結(jié)

因?yàn)槠邢?,留下一些小問題供大家思考:

閉包一定會(huì)導(dǎo)致內(nèi)存不可被回收?

如何監(jiān)控一個(gè) Node.js 服務(wù)的內(nèi)存開銷,如何處理不可預(yù)知的內(nèi)存泄漏?

作者:肖沐宸,github。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/89557.html

相關(guān)文章

  • JavaScript、Node.js與V8的關(guān)系

    對(duì)于了解Node的開發(fā)人員,我們都知道Node是基于Chrome V8引擎開發(fā)的能使JavaScript在服務(wù)器端運(yùn)行的運(yùn)行時(shí)環(huán)境(runtime environment)。一方面,它提供了多種可調(diào)用的API,如讀寫文件、網(wǎng)絡(luò)請(qǐng)求、系統(tǒng)信息等。另一方面,因?yàn)镃PU執(zhí)行的是機(jī)器碼,它還負(fù)責(zé)將JavaScript代碼解釋成機(jī)器指令序列執(zhí)行,這部分工作是由V8引擎完成。 Motivation JavaS...

    Cciradih 評(píng)論0 收藏0
  • JavaScript 工作原理之六-WebAssembly 對(duì)比 JavaScript 其使用場(chǎng)景

    摘要:現(xiàn)在,我們將會(huì)剖析的工作原理,而最重要的是它和在性能方面的比對(duì)加載時(shí)間,執(zhí)行速度,垃圾回收,內(nèi)存使用,平臺(tái)訪問,調(diào)試,多線程以及可移植性。目前,是專門圍繞和的使用場(chǎng)景設(shè)計(jì)的。目前不支持多線程。 原文請(qǐng)查閱這里,略有改動(dòng),本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原理的第六章...

    jay_tian 評(píng)論0 收藏0
  • javascript典型內(nèi)存泄漏chrome的排查方法

    摘要:的內(nèi)存泄漏對(duì)于這門語言的使用者來說,大多數(shù)的使用者的內(nèi)存管理意識(shí)都不強(qiáng)。內(nèi)存泄漏的定義指由于疏忽或錯(cuò)誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存的情況。 javascript的內(nèi)存泄漏 對(duì)于JavaScript這門語言的使用者來說,大多數(shù)的使用者的內(nèi)存管理意識(shí)都不強(qiáng)。因?yàn)镴avaScript一直以來都只作為在網(wǎng)頁上使用的腳本語言,而網(wǎng)頁往往都不會(huì)長(zhǎng)時(shí)間的運(yùn)行,所以使用者對(duì)JavaScript的...

    HackerShell 評(píng)論0 收藏0
  • JavaScript 開發(fā)者所需要知道的 V8(一):V8 In NodeJS

    摘要:歡迎來我的博客閱讀開發(fā)者所需要知道的一是一款擁有自動(dòng)垃圾回收功能的編程語言。它隨著的第一版發(fā)布而發(fā)布以及開源。年月,基金宣布和合并,合并版本在未來發(fā)布。年月日,官方公布又一個(gè)新的名為的優(yōu)化編譯器,主要提供的新語法,以及提高性能。 歡迎來我的博客閱讀:「JavaScript 開發(fā)者所需要知道的 V8(一):V8 In NodeJS」 Motivation JavaScript 是一款擁有...

    Lemon_95 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<