Node.js+;推特流媒体内存泄漏
以下是PM2在Ubuntu机器上作为服务运行的。内存占用从40MB稳步增加到95MB,此时服务器停止发射,但不会使PM2进程崩溃。这导致网页没有响应 这段代码只要在接收到Tweet时发送一个套接字emit。当无人连接时,它不会发出事件,但内存使用率仍在增加,因此它可能与SocketIO无关 只是想知道client.stream中的什么可能会导致此泄漏。我安装了memwatch,但什么也没出现Node.js+;推特流媒体内存泄漏,node.js,twitter,socket.io,Node.js,Twitter,Socket.io,以下是PM2在Ubuntu机器上作为服务运行的。内存占用从40MB稳步增加到95MB,此时服务器停止发射,但不会使PM2进程崩溃。这导致网页没有响应 这段代码只要在接收到Tweet时发送一个套接字emit。当无人连接时,它不会发出事件,但内存使用率仍在增加,因此它可能与SocketIO无关 只是想知道client.stream中的什么可能会导致此泄漏。我安装了memwatch,但什么也没出现 var express = require('express'); var Twitter = requ
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);
});
编辑:我删除了流中的所有内容。在('data')块上,内存使用量仍在增加。这是人们在开始使用PM2时会问的一个常见问题,并且能够清楚地看到内存使用情况。js使用Google的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,那么当进程空闲时,内存占用应该保持在相同的水平