概述
我过去做过一些关于 JavaScript 内存管理的阅读,并且意识到循环 DOM 引用等问题。
但是,我仍然有点不舒服,因为这转换为服务器端JavaScript环境,例如node.js,更具体地说是在express上编写的API。
以此示例文件为例(我们称之为服务器.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);
});
问题(假设这是一个高负载站点(
npm_moduleA
的生命周期是什么?它是在服务器启动的那一刻创建的,但是当(如果有的话,GC 会针对它启动(时 - 我猜它永远不会被触及,因为它在全局范围内?
在"/api/bar/"中,是否应该在每次请求后删除
npm_moduleB
?或者应该单独留给指导性委员会。npm_moduleA
的全局实例化是否比重复npm_moduleB
的实例化(和可能的删除(更有效?
引用
- JavaScript 内存管理
- JavaScript 中的内存泄漏模式
- 什么是 JavaScript 垃圾回收?
- Backbone.js 和 JavaScript 垃圾收集
由于节点.js不会为每个调用创建和销毁运行上下文,因此npm_moduleA
和npm_moduleB
都将存在(在缓存中(,直到您终止服务器。
事实上,无论你在哪里需要模块,它都只是得到一个指向模块入口点的指针。 它在运行时不实例化任何事物。
下面是一个示例:
索引.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(( 放在全局范围内一次。 不要在回调中做 require,因为 require(( 有一些文件名解析工作要做,它与全局范围内的 require 没有区别(在任何方面(。
但是如果你要实例一个类new SomeClass()
,那么你在哪里做它很重要。