11

概要

過去に JavaScript のメモリ管理について読んだことがあり、循環 DOM 参照などの問題を認識しています。

ただし、これはnode.jsなどのサーバー側の JavaScript 環境、より具体的には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_moduleA(npm_moduleBキャッシュ内で) 存続します。

実際、モジュールが必要な場所に関係なく、モジュールのエントリ ポイントへのポインタを取得するだけです。実行時には何もインスタンス化されません。

以下に例を示します。

index.js

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

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

test();

module.js

module.exports = {};

コンソール出力:

10

この場合、require() を一度グローバル スコープに置くだけです。コールバックで require を実行しないでください。require() にはファイル名の解決作業が必要であり、グローバル スコープでは (あらゆる点で) require と違いがないためです。

しかし、クラスをインスタンス化する場合はnew SomeClass()、どこでそれを行うかが重要です。

于 2012-05-16T08:36:10.067 に答える