V8中一個微妙的內(nèi)存泄露方式

寫在最前

本次的分享一段代碼來重新認(rèn)識在V8的垃圾回收機制败明。
歡迎關(guān)注我的博客隘马,不定期更新中——

一段來自meteor工程師提出的導(dǎo)致內(nèi)存泄漏的代碼

var theThing = null  
var replaceThing = function () {
  var originalThing = theThing
  var unused = function () {
    if (originalThing)
      console.log("hi")
  }
  theThing = {
    longStr: new Array(1000000).join('*'),
    someMethod: function () {
      console.log(someMessage)
    }
  };
};
// setInterval(replaceThing, 1000)

打印內(nèi)存快照

1、首先打開一個空白的html肩刃,以防其他變量干擾祟霍。

2、將這段代碼輸入到命令行中盈包,并運行一次replaceThing()

3沸呐、打印堆快照:

image

4、在window/:file// window/下找到在控制臺打印的變量

image

可以看出此時的someMethod雖然沒有在函數(shù)體中留有對originalThing的引用呢燥,但事實是函數(shù)運行后someMethod被輸出到了全局崭添,其內(nèi)部有著對originalThing的引用導(dǎo)致其不會得到釋放∨寻保可想而知如果繼續(xù)運行replaceThing呼渣,那么originalThing會被賦值為theThing同時其中的someMethod還保有著上一次originalThing對象引用,從而形成了一個循環(huán)引用寞埠,內(nèi)部變量全都不會被釋放掉從而導(dǎo)致內(nèi)存的增長屁置。運行多次后打印快照可看到如下結(jié)果:

從打印快照的結(jié)果不難理解之前所說的由于循環(huán)引用而導(dǎo)致內(nèi)部變量釋放不掉從而內(nèi)存占用過多的事實。

So Why仁连?

我們可以知道在這個最關(guān)鍵的someMethod方法中并沒有對originalThing的引用蓝角!只有unused方法引用了originalThing,但unused方法又沒有形成閉包饭冬。那么到底是哪里疏漏了呢使鹅?

來看下來自meteor-blog的解釋:

Well, the typical way that closures are implemented is that every function object has a link to a dictionary-style object representing its lexical scope. If both functions defined inside replaceThing actually used originalThing, it would be important that they both get the same object, even if originalThing gets assigned to over and over, so both functions share the same lexical environment. Now, Chrome’s V8 JavaScript engine is apparently smart enough to keep variables out of the lexical environment if they aren’t used by any closures - from the Meteor blog.

原文出自Node.js Garbage Collection Explained

個人認(rèn)為關(guān)鍵在于這句話:

If both functions defined inside replaceThing actually used originalThing, it would be important that they both get the same object, even if originalThing gets assigned to over and over, so both functions share the same lexical environment.

那么個人理解為:someMethod與unused方法定義在了同一個父級作用域內(nèi)也就是同一個函數(shù)內(nèi),那么這兩個方法將共享相同的作用域昌抠,可見unused持有了對originalThing引用患朱,即便它沒有被調(diào)用,同時someMethod形成閉包導(dǎo)出到全局炊苫,這個時候someMethod會一直保持裁厅,同時由于共享了作用域則強制originalThing不被回收冰沙。故而導(dǎo)致最后的內(nèi)存泄漏。也就是我們在上圖中看到的someMethod方法在context中嵌套包含了originalThing對象姐直,導(dǎo)致內(nèi)存增長的結(jié)果倦淀。

最后

不定時更新中——
有問題歡迎在issues下交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末声畏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子姻成,更是在濱河造成了極大的恐慌插龄,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件科展,死亡現(xiàn)場離奇詭異均牢,居然都是意外死亡,警方通過查閱死者的電腦和手機才睹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門徘跪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人琅攘,你說我怎么就攤上這事垮庐。” “怎么了坞琴?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵哨查,是天一觀的道長。 經(jīng)常有香客問我剧辐,道長寒亥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任荧关,我火速辦了婚禮溉奕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忍啤。我一直安慰自己加勤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布檀轨。 她就那樣靜靜地躺著胸竞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪参萄。 梳的紋絲不亂的頭發(fā)上卫枝,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音讹挎,去河邊找鬼校赤。 笑死吆玖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的马篮。 我是一名探鬼主播沾乘,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼浑测!你這毒婦竟也來了翅阵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤迁央,失蹤者是張志新(化名)和其女友劉穎掷匠,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岖圈,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡讹语,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜂科。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顽决。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖导匣,靈堂內(nèi)的尸體忽然破棺而出才菠,到底是詐尸還是另有隱情,我是刑警寧澤逐抑,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布鸠儿,位于F島的核電站,受9級特大地震影響厕氨,放射性物質(zhì)發(fā)生泄漏进每。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一命斧、第九天 我趴在偏房一處隱蔽的房頂上張望田晚。 院中可真熱鬧,春花似錦国葬、人聲如沸贤徒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽接奈。三九已至,卻和暖如春通孽,著一層夾襖步出監(jiān)牢的瞬間序宦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工背苦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留互捌,地道東北人潘明。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像秕噪,于是被迫代替她去往敵國和親钳降。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容