2015-10-05 82 views
0

我想處理一個大陣,但對象有時是如此之大,它打破與服務器:如何處理大對象並避免內存不足錯誤?

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory

我可以通過做node --max-old-space-size=100,然後運行我的本地處理重現此。沒有設置這個選項,它工作正常。

在此處,它打破

function setManagers(json){ 
return Q.all(json.map(function(obj){ 
    return getUserByUsername(obj.username) 
    .then(function(user){ 
     console.log('got here'); //never hits 
     ... 

function getUserByUsername(username){ 
    console.log('getting user'); //hits 
    return UserModel.findOneQ({username:username}) 
    .then(function(user){ 
     console.log('search finished'); //never hits 
     if(user){ 
      console.log('got user'); 
      return Q(user); 
     }else{ 
      console.log('no user'); 
      return Q.reject({message:'user ' + username + ' could not be found locally'}); 
     } 
    }); 
} 

我認爲這個問題是由於它是一個巨大的數組,其中有一個長的一段代碼5000

如果我要刪除選項來限制我的記憶,或使用較小的數據集,它會工作。

有沒有簡單的方法可以避免這個錯誤?

+0

一個顯而易見的解決辦法是通過某種分塊或批處理來減小數組的大小,對吧? –

+0

將數組保存到一個文件,並且當你需要打開文件並逐行閱讀時會是一個解決方案 – Adem

+2

我不認爲數組的大小是真正的問題,而是事實上對於數組中的每個元素,你正在執行一個數據庫查詢。這應該通過一個查詢或幾個查詢來完成,而不是5000個同時查詢。 –

回答

0

問題是您正在同時進行太多的數據庫調用。

我會改變你的邏輯,向數據庫發送一個排序後的字符串,所有的用戶名都以逗號連接,我會同時獲得所有用戶。然後,我會循環訪問這些用戶,並對您從數據庫接收的用戶執行任何操作。


另一種解決方案,這將不會是突兀到當前的邏輯,是一個接一個,執行數據庫操作中使用,例如,一個承諾,而:

function pwhile(condition, body) { 
    var done = Q.defer(); 

    function loop() { 
    if (!condition()) 
     return done.resolve(); 
    Q.when(body(), loop, done.reject); 
    } 

    Q.nextTick(loop); 

    return done.promise; 
} 

function setManagers(json) { 
    var i = 0; 
    return pwhile(function() { i < json.length; }, function() { 
    var p = getUserByUsername(json[i].username); 
    i++; 
    return p; 
    }); 
} 
相關問題