gpt4 book ai didi

JavaScript 内存泄漏 (Node.js/Restify/MongoDB)

转载 作者:数据小太阳 更新时间:2023-10-29 04:44:15 26 4
gpt4 key购买 nike

更新 4:通过在函数外部实例化 restify 客户端(参见 controllers/messages.js)并在每次请求后调用 global.gc() ,内存增长率似乎已降低很多(每 10 秒约 500KB)。然而,内存使用量仍在不断增长。

更新 3:遇到这篇文章:https://journal.paul.querna.org/articles/2011/04/05/openssl-memory-use/

可能值得注意的是,我将 HTTPS 与 Restify 结合使用。

更新 2:将下面的代码更新为当前状态。我试过用 Express 替换 Restify。遗憾的是,这没有任何区别。似乎链末端的 api 调用(restify -> mongodb -> 外部 api)导致所有内容都保留在内存中。

更新 1:我已将 Mongoose 替换为标准的 MongoDB 驱动程序。内存使用量似乎增长得不那么快,但泄漏仍然存在。


这几天我一直在努力寻找这个漏洞。

我正在使用 Restify 运行 API和 Mongoose对于每个 API 调用,我至少进行一次 MongoDB 查找。我有大约 1-2k 用户在一天内多次访问 API。

我尝试过的

  • 我已将我的代码隔离为仅使用 Restify 并使用 ApacheBench 来触发大量请求 (100k+)。测试期间内存使用量保持在 60MB 左右。
  • 我已将我的代码隔离为仅使用 Restify 和 Mongoose,并按照与上述相同的方式对其进行了测试。内存使用量保持在 80MB 左右。
  • 我已经使用 ApacheBench 在本地测试了完整的生产代码。内存使用量保持在 80MB 左右。
  • 我已经每隔一段时间自动转储堆。我拥有的最大堆转储是 400MB。我只能看到有大量的字符串和数组,但我无法清楚地看到其中的模式。

那么,可能出了什么问题?

我只使用一个 API 用户完成了上述测试。这意味着 Mongoose 只会一遍又一遍地抓取相同的文档。与生产环境的不同之处在于,许多不同的用户访问了 API,这意味着 mongoose 获得了很多不同的文档。

当我启动 nodejs 服务器时,内存迅速增长到 100MB-200MB。它最终稳定在 500MB 左右。这是否意味着它会泄漏每个用户的内存?一旦每个用户都访问过 API,它就会稳定下来吗?

我在下面包含了我的代码,其中概述了我的 API 的一般结构。我很想知道我的代码中是否存在严重错误,或者是否有任何其他方法可以找出导致高内存使用率的原因。

代码

app.js

var restify = require('restify');
var MongoClient = require('mongodb').MongoClient;

// ... setup restify server and mongodb

require('./api/message')(server, db);

api/message.js

module.exports = function(server, db) {

// Controllers used for retrieving accounts via MongoDB and communication with an external api
var accountController = require('../controllers/accounts')(db);
var messageController = require('../controllers/messages')();

// Restify bind to put
server.put('/api/message', function(req, res, next) {
// Token from body
var token = req.body.token;

// Get account by token
accountController.getAccount(token, function(error, account) {

// Send a message using external API
messageController.sendMessage(token, account.email, function() {
res.send(201, {});
return next();
});
});
});
};

controllers/accounts.js

module.exports = function(db) {

// Gets account by a token
function getAccount(token, callback) {
var ObjectID = require('mongodb').ObjectID;

var collection = db.collection('accounts');

collection.findOne({
token: token
}, function(error, account) {

if (error) {
return callback(error);
}

if (account) {
return callback('', account);
}

return callback('Account not found');
});
}
};

controllers/messages.js

module.exports = function() {

function sendMessage(token, email, callback) {

// Get a token used for external API
getAccessToken(function() {}

// ... Setup client

// Do POST
client.post('/external_api', values, function(err, req, res, obj) {
return callback();
});

});
}

return {
sendMessage: sendMessage
};
};

疑似泄漏的堆快照 enter image description here

最佳答案

可能是 getter 中的错误,我在为 mongoose 模式使用虚拟或 getter 时得到它 https://github.com/LearnBoost/mongoose/issues/1565

关于JavaScript 内存泄漏 (Node.js/Restify/MongoDB),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22576402/

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