【问题标题】:How to avoid memory conflicts on ExpressJS/Node.js如何避免 ExpressJS/Node.js 上的内存冲突
【发布时间】:2013-08-22 13:39:57
【问题描述】:

我正在使用 Express 和 Passport for node.js 构建一个简单的 Web 服务器,我编写了一个简单的模块,然后我在 GET 请求中加载了该模块,一切正常,直到多个用户访问该请求。

我曾经相信“app.get”函数中的“var”在函数完成后从内存中删除,但事实并非如此,我在外部模块中使用了一些局部变量,并且值正在在用户之间共享,模块如下所示:

var some_value=0;
function some_method(){
    some_value++;
    return some_value;
}
exports.some_method = some_method;

Express 请求代码如下所示:

app.get('/someurl', function(req, res) {
    var some_extermal_module = require('/some_extermal_module'); // <-----Right way?
    var data = some_extermal_module.some_method();
    res.render('view', {
        title : 'Title',
        data_to_vew: data
    });
});

“app.get”请求中的对象始终保留在内存中,无论是否被其他用户访问?

如何在运行后清理“var”对象?

如何避免这种内存冲突?

我是否必须对模块进行不同的编码或对模块进行不同的调用?

非常感谢。

更新:我想这是一个合适的解决方案,但我需要一些 node.js/Express 专家的审核才能批准或更正。

app.js:

var ext_mod = require('./module');

var express = require('express');
var app = express();

app.get('/', function(req, res){
    var ex_mod_instance = new ext_mod({});
    ex_mod_instance.func_a({},function(ret){
        res.send('Hello World: '+ret);
    });
    ex_mod_instance = null; // clean
});

app.listen(8080);
console.log('Listening on port 8080');

module.js:

var node_module = function(config) {
    this.config = config;
    this.counter=0;
};

node_module.prototype = {
    func_a: function(param,done) {
        this.counter++;
        done(this.counter);
    },
    func_b: function(param,done) {
    }
};

module.exports = node_module;

这是节省内存(泄漏)的最佳方式吗?

【问题讨论】:

    标签: node.js memory module express conflict


    【解决方案1】:

    每次调用函数时,都会在本地范围内获得“干净”的局部变量。模块的目的是编写干净、有组织的代码,这样您就不会在全局范围内拥有所有函数和变量。我相信require 确实缓存了模块,因此您可能在从模块导出的函数周围的闭包中遇到变量问题。您必须包含更多代码。

    解决此问题的一种方法是导出创建模块的函数。该函数可能是您的构造函数,它将在本地限定您的计数器。

    同样,这是一种解决方案。

    【讨论】:

    • 谢谢,我忘记了模块缓存,你知道如何正确执行此操作的在线指南/示例吗?
    【解决方案2】:

    您的变量“some_value”在模块的上下文中是全局的。所以每次请求使用这个模块时,都会使用同一个变量。

    (Require 会缓存仅第一次加载的模块)

    我可以想到两种方法来实现这一点:

    • 您希望每个请求一个变量,并在模块函数中声明此变量,如果您想在同一请求期间在多个函数中使用它,则在 res.locals.some_value 中声明此变量
    • 要么您希望每个用户一个变量,然后您需要使用 express session 中间件,并将变量添加到 req.session.some_value

    【讨论】:

    • 谢谢,我查看了一些 node.js 模块以了解它们是如何制作的以及它们是如何工作的,并尝试做同样的事情,看起来它可以工作,但我不知道它是否是理想的代码,检查更新。
    • 如果你只想在这个请求中保留你的计数器变量,那么我认为不需要 new/class 的东西。一个简单的module.exports = function () {var counter = 0; return {a:function (){}, b:function (){} };}; 就可以了。
    • 你说得对,但我实际上需要的是一个具有多种方法的复杂模块,我希望这是复杂模块的一个好习惯,并且不会因为我找不到内存而吃掉内存很好的在线资源,它教授如何做更高级的事情,而不是经典的“hello world”示例,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 2016-12-20
    • 2019-05-16
    相关资源
    最近更新 更多