gpt4 book ai didi

memory-leaks - 如何解码 node.js 中内存数据的含义并调试内存泄漏?

转载 作者:搜寻专家 更新时间:2023-10-31 22:23:42 24 4
gpt4 key购买 nike

我有一个 RSS 到 MongoDB 阅读器/抓取器,它运行的数据集大于我的系统的内存容量。当我遍历数据时,系统变慢了。我有理由相信这是因为我的内存不足。

我添加了一些调试信息并做了一些更改,但我不知道如何阅读调试输出中给出的信息。

这是一个调试输出示例(在它变得致命之前):

 100 items 
Memory: { rss: 11104256, // what is RSS?
vsize: 57507840, // what is VSIZE?
heapTotal: 4732352, // heapTotal?
heapUsed: 3407624 } // heapUsed?
200 items
Memory: { rss: 12533760,
vsize: 57880576,
heapTotal: 6136320,
heapUsed: 3541984 }
// what key numbers do I watch for?
// when do I reach 'situation critical'?
// how do I free up memory to prevent problems?

此外,如果它有帮助并且为了更好地说明,我提供了一个代码示例。我已经做出的一项更改是将所有 require 语句移到 GrabRss 函数之外。

var http    = require('http');
var sys = require('sys');
var xml2js = require('xml2js');
var util = require('util');
var Db = require('../lib/mongodb').Db,
Conn = require('../lib/mongodb').Connection,
Server = require('../lib/mongodb').Server,
// BSON = require('../lib/mongodb').BSONPure;
BSON = require('../lib/mongodb').BSONNative;

GrabRss = function(grab, start) {
var options = {
host: 'www.example.com',
port: 80,
path: '/rss/'+grab+'/'+start
};

var data;
var items;
var checked = 0;
var len = 0;

GotResponse = function(res) {
var ResponseBody = "";
res.on('data', DoChunk);
res.on('end', EndResponse);

function DoChunk(chunk){
ResponseBody += chunk;
}
function EndResponse() {
//console.log(ResponseBody);
var parser = new xml2js.Parser();
parser.addListener('end', GotRSSObject);
parser.parseString(ResponseBody);
}
}

GotError = function(e) {
console.log("Got error: " + e.message);
}

GotRSSObject = function(r){
items = r.item;
//console.log(sys.inspect(r));

var db = new Db('rss', new Server('localhost', 27017, {}), {native_parser:false});
db.open(function(err, db){
db.collection('items', function(err, col) {
len = items.length;
if (len === 0) {
process.exit(0);
}
for (i in items) {
SaveItem(item[i], col);
}
});
});
}

SaveMovie = function(i, c) {
c.update({'id': i.id}, {$set: i}, {upsert: true, safe: true}, function(err){
if (err) console.warn(err.message);
if (++checked >= len) {
if (checked < 5000) {
delete data; // added since asking
delete items; // added since asking

console.log(start+checked);
console.log('Memory: '+util.inspect(process.memoryUsage()));
GrabRss(50, start+checked);
} else {
console.log(len);
process.exit(0);
}
} else if (checked % 10 == 0) {
console.log(start+checked);
}
});
}
http.get(options, GotResponse).on('error', GotError);

}
GrabRss(50, 0);

最佳答案

通读这段代码后,我确实看到 GotRSSObject 中的 items 被声明为全局的,因为没有 var 作为它的前缀。

除此之外,我没有看到其他明显的内存泄漏。一个好的基本技术是添加一些更多的打印语句来查看内存被分配到哪里,然后通过断言变量 == null 来检查您希望清理内存的位置。

node.js 和 v8 的内存问题在于它不能保证在任何时候都被垃圾回收,而且 afaik,你不能强制垃圾回收发生。您需要限制正在处理的数据量以轻松容纳在内存中,并提供一些错误处理(可能使用 setTimeout 或 process.nextTick)以等待内存被清理干净。

关于 nextTick 的建议 - 这是一个非常非常快的调用。众所周知,Node.js 在事件循环上是单线程的。使用 nextTick 将在下一个循环中真正执行该函数 - 确保您不会经常调用它,否则您会发现自己在浪费周期。

关于rss, vsize, heapTotal, heapUsed ... vsize 是您的进程正在使用的整个内存大小,rss 是实际物理 RAM 中的内存大小,而不是交换内存。 heaptotalheapUsed 指的是您无法控制的 v8 底层存储。您将主要关注 vsize,但您也可以使用 top 或 OS X 上的 Activity Monitor 获得更详细的信息(任何人都知道 *nix 上好的流程可视化工具系统?)。

关于memory-leaks - 如何解码 node.js 中内存数据的含义并调试内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6170174/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com