节点在简单循环中耗尽内存

时间:2015-12-02 17:29:45

标签: node.js mongoose garbage-collection

尝试进行一些地理空间性能压力测试。

我有以下代码 (我不能 - 用grunt issue展示-gc,所以我不能调用global.gc())。

    var getRandomRange = function(start, end){
        return parseFloat((Math.random() * (start - end) + end).toFixed(4));
    }

    /* Max and min long and lat.
    Latitude : max/min +90 to -90
    Longitude : max/min +180 to -180
    */
    var createRandomSeeds = function(index)
    {
        var createSeedsTestPropertyData = [];
        for(var i = 0; i < 1000; i++)
        {
            createSeedsTestPropertyData.push({
                name:i.toString(),
                location: [
                  getRandomRange(+90, -90), getRandomRange(+180, -180)
                ]
            });
        }

        //Mongoose create records.
        Property.create(createSeedsTestPropertyData);
        console.log('Created many records, ' + index);
    }

    for(var i = 0; i < 1000; i++)
    {
        createRandomSeeds(i);
    }

我假设该节点会自动释放内存。

现在我已经闲暇时间超过2小时,因为我无法接受检验。

有谁知道我可以做些什么来避免这种情况? (V4.2.1)

<--- Last few GCs --->

   31667 ms: Scavenge 1401.8 (1457.0) -> 1401.8 (1457.0) MB, 8.6 / 0 ms (+ 2.4 ms in 1 steps since last GC) [allocation failure] [incremental marking delaying mark-sweep].
   32749 ms: Mark-sweep 1401.8 (1457.0) -> 1401.8 (1456.0) MB, 1082.0 / 0 ms (+ 3.4 ms in 2 steps since start of marking, biggest step 2.4 ms) [last resort gc].
   33867 ms: Mark-sweep 1401.8 (1456.0) -> 1401.6 (1457.0) MB, 1118.0 / 0 ms [last resort gc].

1 个答案:

答案 0 :(得分:1)

您可以利用Property.create的异步特性,在代码等待创建记录时允许GC发生。在当前形式中,您的代码会同步对所有1M记录进行排队以创建。

您可以通过在callback调用已完成时调用的createRandomSeeds方法中添加Property.create参数来执行此操作,然后将同步for循环替换为与whilst库的async方法异步迭代。

但我还建议不要在一次create电话中创建1000个文档; 100可能是合理的最大值。请注意以下示例中的更改:

var createRandomSeeds = function (index, callback) {
    var createSeedsTestPropertyData = [];
    for (var i = 0; i < 100; i++) {
        createSeedsTestPropertyData.push({
            name: i.toString(),
            location: [
              getRandomRange(+90, -90), getRandomRange(+180, -180)
            ]
        });
    }

    Property.create(createSeedsTestPropertyData, function(err) {
        console.log('Created many records, ' + index);
        callback(err);
    });
}

var i = 0;
async.whilst(
    // Keep looping asynchronously while i < 10000
    function () { return i < 10000; },
    function (callback) {
        i++;
        createRandomSeeds(i, callback);
    },
    function (err) {
        console.log('All done');
    }
);