2

私の問題は「メモリリーク」ではなく、node.js(expressjs)アプリの「メモリパージ」に関するものです。

私のアプリは、サービス中の高速ルックアップのために、いくつかのオブジェクトをメモリに保持する必要があります。アプリを起動してから当分の間(1〜2日)、すべてが正常に見えましたが、オブジェクトがパージされた(未定義)ために突然Webクライアントがオブジェクトを検索できなくなりました。Javascript GC(ガベージコレクション)が疑われます。ただし、psedu-codeでわかるように、GCがオブジェクトをパージしないように、オブジェクトをnode.jsの「グローバル」変数プロパティに割り当てました。この問題の原因を教えてください。

よろしくお願いします〜

私のnode.js環境は、node.js 0.6.12、expressjs 2.5.8、およびVMWarecloudfoundryノードホスティングです。

これが私のapp.js擬似コードです:

var express = require("express");
var app = module.exports = express.createServer();

// myMethods holds a set of methods to be used for handling raw data.
var myMethods = require("myMethods");

// creates node.js global properties referencing objects to prevent GC from purging them
global.myMethods = myMethods();
global.myObjects = {};

// omited the express configurations

// creates objects (data1, data2) inside the global.myObjects for the user by id.
app.post("/createData/:id", function(req, res) {

    // creates an empty object for the user.
    var myObject = global.myObjects[req.prams.id] = {};

    // gets json data.
    var data1 = JSON.parse(req.body.data1);
    var data2 = JSON.parse(req.body.data2);

    // buildData1 & buildData2 functions transform data1 & data2 into the usable objects.
    // these functions return the references to the transformed objects.
    myObject.data1 = global.myMethods.buildData1(data1);
    myObject.data2 = global.myMethods.buildData2(data2);

    res.send("Created new data", 200);
    res.redirect("/");
});

// returns the data1 of the user.
// Problem occurs here : myObject becomes "undefined" after one or two days running the service.
app.get("/getData1/:id", function(req, res) {

    var myObject = global.myObjects[req.params.id];
    if (myObject !== undefined) {
        res.json(myObject.data1);
    } else {
        res.send(500); 
    }
});

// omited other service callback functions.

// VMWare cloudfoundry node.js hosting.
app.listen(process.env.VCAP_APP_PORT || 3000);
4

3 に答える 3

2

あらゆる種類のキャッシュシステム(自社製品かサードパーティ製品かを問わず)がこのシナリオを考慮に入れる必要があります。インメモリキャッシュで常に利用可能なデータに依存するべきではありません。メモリ内のデータが失われる原因となる可能性のあるものが多すぎます(マシンの再起動、プロセスの再起動など)。

あなたの場合、データがキャッシュにあるかどうかを確認するためにコードを更新する必要があるかもしれません。キャッシュにない場合は、永続ストレージ(データベース、ファイル)からフェッチし、キャッシュして続行します。

于 2012-06-26T14:03:23.087 に答える
2

Haesungとまったく同じように、データベースを使用せずにプログラムをシンプルに保ちたいと思いました。そして、Haesungのように、Node.js(およびexpress)での私の最初の経験は、この奇妙なパージを観察することでした。混乱しましたが、数百行のjsonファイルを管理するためのストレージソリューションが必要であることを本当に受け入れませんでした。私にとって電球の瞬間は私がこれを読んだときでした

モジュールにコードを複数回実行させる場合は、関数をエクスポートして、その関数を呼び出します。

これはhttp://nodejs.org/api/modules.html#modules_cachingから取得されます。したがって、必要なファイル内の私のコードはこれから変更されました

var foo = [{"some":"stuff"}];
export.foo;

それに

export.foo = function (bar) {
var foo = [{"some":"stuff"}];
return foo.bar;
}

そしてそれはうまくいきました:-)

于 2013-05-13T21:02:46.130 に答える
0

次に、ファイルシステムを使用することをお勧めします。4KBのオーバーヘッドは、目標とハードウェアにとって大きな問題ではないと思います。フロントエンドのJavaScriptに精通している場合、これは役立つ可能性がありますhttps://github.com/coolaj86/node-localStorage

于 2012-06-26T08:20:45.040 に答える