微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

Update3:看过这篇文章https://journal.paul.querna.org/articles/2011/04/05/openssl-memory-use/

值得注意的是,我正在使用HTTPS和Restify.

更新2:将以下代码更新为当前状态.我试过用Express换掉Restify.可悲的是,这并没有任何区别.似乎链的末尾的api调用(restify – > mongodb – >外部api)导致一切都保留在内存中.

更新1:我用标准的MongoDB驱动程序替换了Mongoose.内存使用似乎增长速度较慢,但​​泄漏仍然存在.

我一直在努力尝试找到这个泄漏几天了.

我正在使用RestifyMongoose运行API,并且对于每个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();
            });
        });
    });
};

控制器/ 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
        },account) {

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

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

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

控制器/ 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,obj) {
                return callback();
            });

        });
    }

    return {
        sendMessage: sendMessage
    };
};

怀疑泄漏的快照

解决方法

可能是getter中的一个bug,我在使用mongoose schema https://github.com/LearnBoost/mongoose/issues/1565的虚拟或getter时得到了它

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


什么是深拷贝与浅拷贝?深拷贝与浅拷贝是js中处理对象或数据复制操作的两种方式。‌在聊深浅拷贝之前咱得了解一下js中的两种数据类型:
前言 今天复习了一些前端算法题,写到一两道比较有意思的题:重建二叉树、反向输出链表每个节点 题目 重建二叉树: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列 {1,2,4,7,3,5,6,8} 和中序遍历序列 {
最近在看回JavaScript的面试题,this 指向问题是入坑前端必须了解的知识点,现在迎来了ES6+的时代,因为箭头函数的出现,所以感觉有必要对 this 问题梳理一下,所以刚好总结一下JavaScript中this指向的问题。
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高