node内存释放
发布于 7 年前 作者 TalkWIthKeyboard 5449 次浏览 来自 问答

最近刚开始研究垃圾回收,在试着回答饿了么大前端里的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 的闭包,这个闭包不会被回收掉,所以会在内存中一直累积?

因为自己不是很确定,所以麻烦懂的小伙伴回答一下,谢谢!

6 回复

buffer不走v8的local handle分配和释放,也就不属于v8的堆内内存部分,所以没有1.4g的限制,当然爆掉还是会的:你的服務器内存被全部占掉的时候,最后一个泄露的原因可以看我在eleme里面的issue 7,也可以看我之前在cnode的文章

来自酷炫的 CNodeMD

@hyj1991 先谢谢了,还想再问问第二个例子到底是啥意思?

@TalkWIthKeyboard 什么第二个例子?

@hyj1991

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

这个,我确实不太理解。

@TalkWIthKeyboard array.push() 空的形式应该是不会泄露的 v8的源码中我记得处理ArrayPush的函数大致流程是这样:

  • 把 this (即 array 本身)转换成 object ao
  • 获取当前 array 的 length 属性 l1
  • 获取 arguments.length 属性 l2
  • 用一个for循环(条件是 i<l2 ) 把第一步中的 ao[i+l1] 属性赋值 arguments[i]
  • 最后返回新长度

所以你举的例子的情况下,argument.length === 0 ,因此根本没有往数组里加东西,故而也不存在泄漏

@hyj1991 看过源码确实厉害!

回到顶部