第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會有你想問的

使用node.js進(jìn)行垃圾回收

使用node.js進(jìn)行垃圾回收

弒天下 2019-10-29 11:08:54
我很好奇嵌套函數(shù)的node.js模式如何與v8的垃圾收集器一起工作。這是一個(gè)簡單的例子readfile("blah", function(str) {   var val = getvaluefromstr(str);   function restofprogram(val2) { ... } (val)})如果restofprogram是長時(shí)間運(yùn)行的,這是否意味著str永遠(yuǎn)不會收集垃圾?我的理解是,使用結(jié)點(diǎn),您最終會獲得很多嵌套函數(shù)。如果在外部聲明了restofprogram,是否會收集垃圾,因此str不能在范圍內(nèi)?這是推薦做法嗎?編輯我不想使問題復(fù)雜化。那只是粗心,所以我修改了它。
查看完整描述

3 回答

?
至尊寶的傳說

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超10個(gè)贊

簡單的答案:如果str沒有從其他任何地方引用的值(并且str本身也沒有從引用restofprogram),則function (str) { ... }返回時(shí)將無法訪問它的值。


詳細(xì)說明:V8編譯器區(qū)分真正的地方,從所謂的變量范圍內(nèi)通過封閉拍攝的變量,由陰影與語句來或eval調(diào)用。


局部變量存在于堆棧中,并在函數(shù)執(zhí)行完成后立即消失。


上下文變量位于分配給堆的上下文結(jié)構(gòu)中。當(dāng)上下文結(jié)構(gòu)消失時(shí),它們消失。這里要注意的重要一點(diǎn)是,來自同一作用域的上下文變量位于同一結(jié)構(gòu)中。讓我用示例代碼進(jìn)行說明:


function outer () {

  var x; // real local variable

  var y; // context variable, referenced by inner1

  var z; // context variable, referenced by inner2


  function inner1 () {

    // references context 

    use(y);

  }


  function inner2 () {

    // references context 

    use(z);

  }


  function inner3 () { /* I am empty but I still capture context implicitly */ } 


  return [inner1, inner2, inner3];

}

在這個(gè)例子中變量x將盡快消失outer的回報(bào),但變量y,并z只有當(dāng)將消失兩個(gè) inner1,inner2 和 inner3死。發(fā)生這種情況是因?yàn)閥和z分配在相同的上下文結(jié)構(gòu)中,并且所有三個(gè)閉包都隱式引用了此上下文結(jié)構(gòu)(即使inner3沒有顯式使用它)。


當(dāng)你開始使用情況變得更加復(fù)雜與語句來,的try / catch語句來其在V8中包含一個(gè)隱含的與語句來里面的catch子句或全局eval。


function complication () {

  var x; // context variable


  function inner () { /* I am empty but I still capture context implicitly */ }


  try { } catch (e) { /* contains implicit with-statement */ }


  return inner;

}

在這個(gè)例子中,x只有在inner死亡時(shí)才會消失。因?yàn)椋?/p>


try / catch-在catch子句中包含 -statement 隱式

V8假定任何帶有 -statement的語句都會遮蓋所有本地人

這迫使x成為上下文變量并inner捕獲上下文,x直到上下文inner消失為止。


通常,如果您要確保給定的變量保留某個(gè)對象的時(shí)間不超過實(shí)際需要的時(shí)間,則可以通過分配給該變量輕松地破壞此鏈接null。


查看完整回答
反對 回復(fù) 2019-10-29
?
智慧大石

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超3個(gè)贊

實(shí)際上,您的示例有些棘手。是故意的嗎?您似乎在用內(nèi)部詞法范圍的restofprogram()的參數(shù)掩蓋了外部val變量val,而不是實(shí)際使用它。但是無論如何,您只是在問一個(gè)問題,str因此val,為簡單起見,讓我忽略示例中的棘手問題。


我的猜測是str,即使沒有使用該變量,也不會在restofprogram()函數(shù)完成之前收集該變量。如果 restofprogram()不使用str 并且不使用eval(),new Function()那么可以安全地收集它,但我懷疑會這樣做。對于V8來說,這將是一個(gè)棘手的優(yōu)化,可能不值得這樣做。如果沒有eval,并new Function()在語言的話,那就好辦多了。


現(xiàn)在,它不必表示它永遠(yuǎn)不會被收集,因?yàn)閱尉€程事件循環(huán)中的任何事件處理程序都應(yīng)該立即完成。否則,您的整個(gè)過程將被阻塞,并且與內(nèi)存中一個(gè)無用的變量相比,您將面臨更大的問題。


現(xiàn)在,我想知道您的意思不是您在示例中實(shí)際寫的。Node中的整個(gè)程序就像在瀏覽器中一樣–它只是注冊事件回調(diào),該回調(diào)在主程序主體完成后異步觸發(fā)。同樣,沒有任何處理程序在阻塞,因此實(shí)際上沒有函數(shù)花費(fèi)任何明顯的時(shí)間來完成。我不確定我是否理解您在問題中的實(shí)際含義,但希望我所寫的內(nèi)容將有助于您理解所有問題。


更新:

在閱讀了有關(guān)程序外觀的注釋中的更多信息之后,我可以說更多。


如果您的程序是這樣的:


readfile("blah", function (str) {

  var val = getvaluefromstr(str);

  // do something with val

  Server.start(function (request) {

    // do something

  });

});

然后,您也可以這樣寫:


readfile("blah", function (str) {

  var val = getvaluefromstr(str);

  // do something with val

  Server.start(serverCallback);

});

function serverCallback(request) {

  // do something

});

這將使strServer.start后走出去的范圍()被調(diào)用,并最終將被收集。而且,這將使您的縮進(jìn)更易于管理,對于更復(fù)雜的程序也不要低估它。


至于val您可能會在這種情況下使其成為全局變量,這將大大簡化您的代碼。當(dāng)然,您不必這樣做,可以與閉包作斗爭,但是在這種情況下,val對于readfile回調(diào)和serverCallback函數(shù)而言,使global全局化或使其處于外部作用域似乎是最簡單的解決方案。


請記住,在任何地方都可以使用匿名函數(shù)時(shí),也可以使用命名函數(shù),對于那些匿名函數(shù),您可以選擇希望它們在哪個(gè)作用域中使用。


查看完整回答
反對 回復(fù) 2019-10-29
  • 3 回答
  • 0 關(guān)注
  • 916 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號