11

概述

我过去读过一些关于 JavaScript 内存管理的文章,并且知道循环 DOM 引用等问题。

但是我仍然有点不舒服,因为这会转化为服务器端 JavaScript 环境,例如node.js,更具体地说是在express上编写的 API 。


获取这个示例文件(我们称之为 server.js)

var npm_moduleA = require('npmA')({ someInitArg : 'blah' }),
    app = express.createServer();

app.get('/api/foo', function (req, res) {

    var result = npm_moduleA.doSomething();
    res.send(result);

});

app.get('/api/bar', function (req, res) {

    var npm_moduleB = require('npmB')({ someInitArg : 'blah' }),
        result = npm_moduleB.doSomethingElse();

    res.send(result);

});

问题(假设这是一个高负载站点)

  1. 的生命周期是npm_moduleA什么?它是在服务器启动的那一刻创建的,但是什么时候(如果有 GC 反对它的话)-我猜它永远不会被触及,因为它在全局范围内?

  2. 在'/api/bar/'中,npm_moduleB每次请求后都应该删除吗?或者这应该单独留给GC。

  3. 的全局实例化是否npm_moduleA比重复的实例化(和可能的删除)更有效npm_moduleB


参考

4

1 回答 1

9

由于 node.js 不会为每个调用创建和销毁运行上下文,因此两者都npm_moduleAnpm_moduleB存在(在缓存中),直到您终止服务器。

事实上,无论你在哪里需要模块,它都只是获得一个指向模块入口点的指针。它在运行时不会实例化任何东西。

这是一个例子:

index.js

var t = require('./module.js');
t.value = 10;

function test() {
  var t2 = require('./module.js');
  console.log(t2.value);
}

test();

模块.js

module.exports = {};

控制台输出:

10

在这种情况下,只需将您的 require()s 放在全局范围内一次。不要在回调中做 requires,因为 require() 有一些文件名解析工作要做,并且它与全局范围内的 require 没有区别(在任何方面)。

但是如果你要实例化一个类new SomeClass(),那么你在哪里做很重要。

于 2012-05-16T08:36:10.067 回答