node 閉包內存釋放

最近在使用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%以上,並且一直存在不會釋放。

最後得出結論,當函數裏面存在內部函數,則形成閉包機制,活動環境中產生的一切變量都會保存在內存中不會釋放。不管該內部函數是否被外部變量引用。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章