4

我正面临一个奇怪的情况。我编写了一个应用程序,它每五分钟执行一次 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);

很简单。问题是,一段时间后,来自 process.memoryUsage() 的“rss”不断攀升。看起来创建的 ClientRequest 对象永远不会被 GCed()。虽然我在这个例子中使用了 https ,但如果使用http 模块也会发生同样的情况。

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

编辑

我已经解决了上面的问题(见下文我的评论)。现在我面临一个不同的问题,这真的非常难以追踪(使用node-webkit-agent来分析内存使用情况,但没有什么特别的。堆对我来说看起来很稳定)。这个场景也没什么特别的,我通过 Streams 将大约 200 张图像从源复制到目标(参见下面的代码)。发生的情况是,“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}
4

0 回答 0