node 闭包内存释放

来源:互联网 发布:计算机图论算法 编辑:程序博客网 时间:2024/05/17 04:50

最近在使用node做游戏服务器架构,其异步回调机制对处理大批量请求非常有效,而且避免了多线程造成的理解困难,死锁等一系列问题。

服务器在外网放了两个星期,一次都没挂过,确实很稳定。

 

但好事不长,游戏上线之前开始做压力测试,当并发数量达到500个时,内存直接达到70%以上,cpu达到100%,导致程序直接崩溃。

node不是有垃圾回收机制吗?怎么还会产生内存泄漏的问题。

后来经过仔细调查,发现是闭包造成的内存泄漏。因为闭包保留了对其作用域内的东西的引用,而这正是通常的内存泄露之源。

好了,举个例子。

 

//第一种情况,变量在外层函数,内层函数引用外层函数的变量。内层函数并没有被全局变量引用,只是执行。

function aa(c)
{
  var ads={};//变量在回调函数外部

  for(var i=0;i<20000000;i++)
  {
   ads[i]=i;
  }
  
  c(ads); 
  
}

 

function bb()

 var num=200;
 aa(function(arr){
  console.log(ads[1]);
 })
}
bb();

setInterval(function(){},1000);//使用定时器保持进程一直在执行状态

 

在Linux上测试发现,内存使用率达到10%以上,并且一直存在不会释放。当执行bb函数是,其内部的函数传入了匿名函数,形成了函数内部存在函数的机制,即闭包。该匿名函数引用了外部函数的变量ads。

 

//第二种情况,变量在回调函数(内层函数)内部。

function aa(c)
{  
  
  c(); 
  
}

 

function bb()

 
 aa(function(){
    var ads={};//变量在回调函数内部

     for(var i=0;i<20000000;i++)
    {
      ads[i]=i;
     }


 })
}
bb();

setInterval(function(){},1000);//使用定时器保持进程一直在执行状态

 

同样,在Linux上测试发现,内存使用率达到10%以上,并且一直存在不会释放。

 

//第三种情况,变量在外层函数,但内部函数并不执行。

function aa(c)

  var ads={};//变量在回调函数内部部

     for(var i=0;i<20000000;i++)
     {
       ads[i]=i;
     }
 
 
}

 

function bb()
{
 
 aa(function(){
   


 })
}
bb();

setInterval(function(){},1000);//使用定时器保持进程一直在执行状态

 

同样,在Linux上测试发现,内存使用率达到10%以上,并且一直存在不会释放。

最后得出结论,当函数里面存在内部函数,则形成闭包机制,活动环境中产生的一切变量都会保存在内存中不会释放。不管该内部函数是否被外部变量引用。