Node.js app在不释放内存的情况下持续消耗内存

时间:2013-10-08 06:08:12

标签: node.js http memory-leaks https garbage-collection

我面临着一种奇怪的情况。我写了一个每五分钟执行一次HTTP GET请求的应用程序。像这样:

// pingy

'use strict';

var https   = require('https'),
    url     = require('url');

exports.ping = function ping (callback) {
    var options = url.parse('https://host.tld/ping');

    callback = callback || function () {};

    https.get(options, function handler (response) {
        var body = '';

        response
            .on('readable', function onReadable() {
                body = body + response.read();
            })
            .on('end', function onEnd() {
                return callback(null, body);
            })
            .on('error', function onError (err) {
                return callback(err);
            });
    });
};

// in other module
var pingy = require('./lib/pingy');

setInterval(pingy.ping, 300000);

非常简单。事情是,过了一段时间," rss"来自process.memoryUsage()攀登和攀登。看起来创建的ClientRequest对象永远不会被GCed()。虽然我在此示例中使用https,但如果使用 http模块,则会发生同样的情况。

你知道这里有什么问题吗?

修改

我已经解决了上述问题(请参阅我的评论中的下文)。现在我面临着一个不同的问题,实际上很难追踪(使用node-webkit-agent来分析内存使用情况,但没有什么特别的。堆对我来说看起来很稳定)。这个场景也没什么特别之处我通过Streams将大约200个图像从源码复制到dest(参见下面的代码)。会发生什么," RSS"也增加了。我很确定我的代码有关如何管道文件的问题。不要误解我的内存使用量没有问题。我有一个问题是,内存永远不会被释放。为了验证将来某些时候将清除内存,我会在复制每个文件后启动http.createServer。即使在几个小时后," rss"价值保持不变。

那么,再说一遍,你知道这里有什么问题吗?每个提示都要提前感谢! :)

'use strict';

var http = require('http'),
    fs   = require('fs'),
    path = require('path'),
    util = require('util'),
    directory = '/path/to/your/files/',
    jobs = [];

function printMemoryUsage () {
    var memory = process.memoryUsage();

    memory.rss = (memory.rss / 1024) | 0;
    memory.heapTotal = (memory.heapTotal / 1024) | 0;
    memory.heapUsed = (memory.heapUsed / 1024) | 0;

    console.log(JSON.stringify(memory));
}

function pipeFile() {
    var infile = jobs.pop(),
        outfile = jobs.pop(),
        instream = fs.createReadStream(infile),
        outstream = fs.createWriteStream(outfile);

    instream.pipe(outstream);

    instream.on('close', outstream.end.bind(outstream));
    outstream.on('finish', function onFinish () {
        // console.log('Finished %s -> %s', infile, outfile);

        instream.destroy();
        outstream.destroy();

        next();
    });
}

function next() {
    if (jobs.length) {
        setTimeout(pipeFile, 2000);
    } else {
        http.createServer(function (req, res) {
            res.writeHead(200, {'Content-Type': 'text/plain'});
            res.end('Fooboot\n');
        }).listen(1337, '127.0.0.1');
    }
}

fs.readdir(directory, function (err, files) {
    files.forEach(function onIteration (file) {
        jobs.push(path.join(__dirname, file)); // outfile
        jobs.push(path.join(directory, file)); // infile
    });
    next();
});

setInterval(printMemoryUsage, 3000);

这些是记忆足迹:

{"rss":13904,"heapTotal":6963,"heapUsed":1758}
{"rss":16012,"heapTotal":6963,"heapUsed":2016}
{"rss":26040,"heapTotal":6963,"heapUsed":2265}
{"rss":31468,"heapTotal":6963,"heapUsed":2453}
{"rss":41080,"heapTotal":6963,"heapUsed":2712}
{"rss":46620,"heapTotal":6963,"heapUsed":2844}
{"rss":49260,"heapTotal":6963,"heapUsed":1999}
{"rss":49524,"heapTotal":6963,"heapUsed":2249}
{"rss":49524,"heapTotal":6963,"heapUsed":2362}
{"rss":49788,"heapTotal":6963,"heapUsed":2621}
{"rss":49788,"heapTotal":6963,"heapUsed":2755}
{"rss":52692,"heapTotal":6963,"heapUsed":2001}
{"rss":52692,"heapTotal":6963,"heapUsed":2138}
{"rss":52692,"heapTotal":6963,"heapUsed":2270}
{"rss":52692,"heapTotal":6963,"heapUsed":2483}
{"rss":52692,"heapTotal":6963,"heapUsed":2600}
{"rss":52692,"heapTotal":6963,"heapUsed":2796}
{"rss":52956,"heapTotal":6963,"heapUsed":1951}
{"rss":52956,"heapTotal":6963,"heapUsed":2079}
{"rss":52956,"heapTotal":6963,"heapUsed":2343}
{"rss":52956,"heapTotal":6963,"heapUsed":2462}
{"rss":52956,"heapTotal":6963,"heapUsed":2689}
{"rss":52956,"heapTotal":6963,"heapUsed":2831}
{"rss":53136,"heapTotal":9011,"heapUsed":1927}
{"rss":53136,"heapTotal":9011,"heapUsed":2176}
{"rss":53136,"heapTotal":9011,"heapUsed":2273}
{"rss":53136,"heapTotal":9011,"heapUsed":2447}
{"rss":53136,"heapTotal":9011,"heapUsed":2545}
{"rss":53136,"heapTotal":9011,"heapUsed":2627}
{"rss":53136,"heapTotal":9011,"heapUsed":2804}
{"rss":53136,"heapTotal":9011,"heapUsed":2890}
{"rss":59732,"heapTotal":9011,"heapUsed":3100}
{"rss":65012,"heapTotal":9011,"heapUsed":3211}
{"rss":73496,"heapTotal":9011,"heapUsed":3409}
{"rss":79304,"heapTotal":9011,"heapUsed":3536}
{"rss":83792,"heapTotal":9011,"heapUsed":3633}
{"rss":95408,"heapTotal":9011,"heapUsed":3865}
{"rss":98840,"heapTotal":9011,"heapUsed":1824}
{"rss":98840,"heapTotal":9011,"heapUsed":2003}
{"rss":98840,"heapTotal":9011,"heapUsed":2205}
{"rss":98840,"heapTotal":9011,"heapUsed":2297}
{"rss":98840,"heapTotal":9011,"heapUsed":2491}
{"rss":98840,"heapTotal":9011,"heapUsed":2608}
{"rss":98840,"heapTotal":9011,"heapUsed":2717}
{"rss":98840,"heapTotal":9011,"heapUsed":2919}
{"rss":99368,"heapTotal":9011,"heapUsed":3036}
{"rss":99368,"heapTotal":9011,"heapUsed":3247}
{"rss":99632,"heapTotal":9011,"heapUsed":3351}
{"rss":99632,"heapTotal":9011,"heapUsed":3452}
{"rss":99896,"heapTotal":9011,"heapUsed":3606}
{"rss":99896,"heapTotal":9011,"heapUsed":3686}
{"rss":105968,"heapTotal":9011,"heapUsed":3824}
{"rss":106760,"heapTotal":9011,"heapUsed":1936}
{"rss":106760,"heapTotal":9011,"heapUsed":2022}
{"rss":106760,"heapTotal":9011,"heapUsed":2187}
{"rss":106760,"heapTotal":9011,"heapUsed":2279}
{"rss":106760,"heapTotal":9011,"heapUsed":2474}
{"rss":106760,"heapTotal":9011,"heapUsed":2614}
{"rss":106760,"heapTotal":9011,"heapUsed":2690}
{"rss":106760,"heapTotal":9011,"heapUsed":2854}
{"rss":106760,"heapTotal":9011,"heapUsed":2953}
{"rss":106760,"heapTotal":9011,"heapUsed":3241}
{"rss":106760,"heapTotal":9011,"heapUsed":3391}
{"rss":106760,"heapTotal":9011,"heapUsed":3535}
{"rss":107288,"heapTotal":9011,"heapUsed":3797}
{"rss":108248,"heapTotal":9011,"heapUsed":1908}

0 个答案:

没有答案