node.js - node垃圾回收、記憶體洩漏相關問題
某草草
某草草 2017-05-16 13:42:15
0
3
736

最近剛開始研究垃圾回收,在試著回答餓了麼大前端裡的node記憶體釋放相關的問題時,遇到了一些疑問:

let arr = [];
while(true)
  arr.push(1);

無限增加的數組,這肯定是會爆掉記憶體的。

let arr = [];
while(true)
  arr.push();

這個我覺得只是一直使用 arr ,導致 arr 不能被釋放吧?

let arr = [];
while(true)
  arr.push(new Buffer(1000));

這個是因為 Buffer 的大小小於8k,會先檢查記憶體池是否已滿,所以應該不會爆掉記憶體?

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)

這個是因為unusedoriginalThing 進行了引用,所以每一個unused 都形成了一個originalThing 的作用域replaceThing 的閉包,這個閉包不會被回收掉,所以會在記憶體中一直累積?

因為自己不是很確定,所以麻煩懂的夥伴回答一下,謝謝!

某草草
某草草

全部回覆(3)
漂亮男人

new Buffer估計不是簡單爆內存的問題,Buffer是分配在V8堆外的,所以實際上比第一個的問題還要嚴重,我剛才就直接死機了。

第二個應該說的是由於數組大小不會成長,所以不會爆內存。

第三個原文就有提及原因

例如上述情況中 unused 的函數中持有了 originalThing 的引用, 使得每次舊的對像不會釋放從而導致內存洩漏

如果還是不懂可以看看原發現者的文章,裡面講解的很詳細。

黄舟

死循環的程式碼到哪裡都會爆內存,特別是js這種單線程語言,直接阻塞卡死。
Buffer類型我沒用過,會不會檢查內存池這個無法確定,但卡死了檢不檢查內存意義也不大。

最後一個我同意你的說法,每次循環都新建一個對象,theThing的引用地址不斷在變化,正常情況下舊的引用對象就應該被垃圾回收了,但由於unused引用了舊的對象originalThing,originalThing又是私有變量,所以舊的物件無法被垃圾回收,就造成了記憶體外洩。

有沒有下面這段程式碼的差別,環境chrome,運行30s。
第一幅圖是沒有這段程式碼的結果,內存在15M浮動。
第二幅圖是有這段程式碼的結果,記憶體不斷成長。

function unused() {
  if (originalThing) console.log("hi");
}

小葫芦

我也不是很確定,不過可以用memwatch-next的包包看看

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板