Node.js + Twitter流内存泄漏

时间:2015-08-12 06:52:24

标签: node.js twitter socket.io

以下内容由PM2在Ubuntu计算机上作为服务运行。内存占用量从40MB稳步上升到95MB,此时服务器停止发射,但不会导致PM2进程崩溃。这导致网页无响应。

此代码只是在收到Tweet时发送套接字发送。当没有人连接但内存使用率仍然增加时,它不会发生事件,因此它可能与SocketIO无关。

只是想知道client.stream中的哪些内容可能导致此泄漏。我安装了memwatch但没有出现。

var express = require('express');
var Twitter = require('twitter');
var login = require('./credentials');

var connections = 0;
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.use(express.static('public'));

String.prototype.startsWith = function(str){
    return this.indexOf(str) === 0;
};

var client = new Twitter({
    consumer_key: login.creds['consumer_key'],
    consumer_secret: login.creds['consumer_secret'],
    access_token_key: login.creds['access_token_key'],
    access_token_secret: login.creds['access_token_secret']
})

client.stream('statuses/filter', {track: 'drake'}, function(stream) {
    stream.on('data', function(tweet) {
        var imageUrl = undefined;
        try {
            imageUrl = tweet.entities.media[0].media_url;
        }
        catch(err) {
            // Ignored
        }
        abridgedTweet = {'text': tweet.text, 'author': tweet.user.screen_name, 'picture': imageUrl};
        if (connections > 0 && !(tweet.text.startsWith("RT")) && !(tweet.text.startsWith("@")) && tweet.lang == "en") {
            io.emit('tweet', abridgedTweet);
        };
    });
    stream.on('error', function(error) {
        console.log("ERROR: " + error);
    })
});

app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
    console.log('A user connected');
    connections += 1;
    socket.on('disconnect', function() {
        console.log("A user disconnected");
        connections -= 1;
        console.log(connections + " users remaining");
    });
});

http.listen(3000, function(){
  console.log('listening on *:3000, pid: ' + process.pid);
});

编辑:我从stream.on('数据')块中删除了所有内容,内存使用量仍在增加。

1 个答案:

答案 0 :(得分:2)

这是人们在开始使用PM2时能够清楚地看到内存使用情况的常见问题。 Node.js使用谷歌的V8 JavaScript引擎,它实现了垃圾收集器。 V8使用的GC算法将尝试占用尽可能多的内存,并且在清理未使用的内存时非常懒惰。因此,通常情况下,节点进程将继续增加内存使用量,直到GC认为更好地释放内存的某个点。请注意,节点进程的硬内存限制为1.4 GB。

有一种方法可以使用--expose-gc标志强制GC释放内存。像这样运行你的服务器:

node --expose-gc yourscript.js

并在应用程序的某处附加以下循环。这将每30秒强制进行垃圾收集。

setInterval(function(){
  global.gc();
  console.log('GC done')
}, 1000*30);

如果你正在使用PM2,你需要做额外的工作来传递--expose-gc标志。注意在实践中你可能应该避免做手动垃圾收集,然后让我们V8完成它的工作。

其次,尽管显然没有做任何事情,你的过程首先增加的原因可能是PM2本身。默认情况下,PM2以群集模式运行,而不是fork模式。群集模式将在后台运行某些进程,从而随着时间的推移增加内存。这个内存最终会在某些时候由GC解除分配。如果在fork模式下运行PM2,则当进程空闲时,内存占用应保持在同一级别。

相关问题