内存泄漏 - 循环中的承诺

时间:2017-11-15 06:08:35

标签: node.js memory-leaks promise bluebird appdynamics

我的节点应用的CPU使用率正在逐渐增加。我发现内存泄漏正在发生。通过AppDynamics,我发现在 processImmediate 调用树下,有大量的保留内存随着时间的推移而不断增加。在我钻研时,我发现问题出在 settlePromises 功能上。

App Dynamics screen shot

我希望得到您对我一直使用的承诺的一种特定用法的看法。承诺的承诺。下面是这种用法的示例函数结构。

var dataArray = []; //list of jsons
var Promise = require('node-promise').Promise;

function doSomething(){
    try{
        var promises = [];
        //create function promises and push
        for(var i in dataArray){
            var usage = {};
            usage["user"] = dataArray[i].user;
            promises.push((function(ob){
                var log = extend({},ob);
                return executeFunction(log)}).bind(null,usage));
        }

        //loop and execute
        var respArray = [];
        return (promises.reduce(function(previous , current , index , array){
            try{
                return previous.then(function(resp){
                    if(resp != null)
                        respArray.push(resp);
                    if(promises.indexOf(current)==promises.length -1){
                        return current();
                    }
                    else{
                        return current();
                    }
                });
            }catch(ex){
                throw { ex : ex.stack};
            }
        },delay())).then(function(){
            return data;
        });
    }
    catch(ex){
        console.log(ex,ex.stack);
        throw { ex : ex.stack};
    }
}

function logTemplate(log){
    return models.Users.create(log).then(function(resp){
        return resp;
    },function(err){
        return err;
    });
}

一小时内的堆增长情况如下图所示

enter image description here

上述函数必须与数据数组中的对象执行同步更新。这有可能导致内存泄漏吗?

1 个答案:

答案 0 :(得分:-1)

不确定它是否会导致内存泄漏,但是你的功能肯定有很多不必要的瑕疵,可以用Bluebird的Promise.mapSeries()和其他蓝鸟助手来清理。

这样做可能有助于减少内存泄漏。

doSomething函数减少到8行:

function doSomething(){
    return Promise.delay(1000)  // <-- specify time
        .return(dataArray)
        .mapSeries(function (el) {
            return executeFunction({ user: el.user });
        })
        .filter(function (result) { 
            return result !== null; 
        });
}