6

私たちのサービスは、クライアントのサーバーで夜間にスリープ状態になり、その後、目覚めるのに苦労する傾向があります。発生しているように見えるのは、プロセスヒープ(場合によっては数百MB)がスワップファイルに移動されることです。これは、当社のサービスが使用されておらず、他のサービス(DBバックアップ、AVスキャンなど)の実行がスケジュールされている夜間に発生します。これが発生すると、数時間非アクティブになった後、サービスへの最初の呼び出しに最大数分かかります(その後の呼び出しには数秒かかります)。

これは仮想メモリ管理の問題であると確信しており、OSにサービスを物理メモリに保持させるという考えは本当に嫌いです。これを行うと、サーバー上の他のプロセスに悪影響を及ぼし、サーバー全体のスループットが低下することを私は知っています。そうは言っても、私たちのクライアントは私たちのアプリが応答することを望んでいます。彼らは毎晩の仕事にもっと時間がかかるかどうか気にしません。

Windowsに物理メモリにページを保持させる方法があることを漠然と覚えていますが、私はその考えを本当に嫌います。私は、より高いレベルの機能を開始する内部または外部のウォッチドッグにもっと傾いています(ほとんど何もせず、違いがない内部スケジューラがすでにいくつかあります)。そのようなサービスを提供するサードパーティのツールがあれば、それは同じくらい良かったでしょう。

この種の問題に対するコメント、推奨事項、および一般的な解決策をお聞かせください。このサービスはVC2005で記述されており、Windowsサーバーで実行されます。

4

5 に答える 5

8

おっしゃったように、アプリを強制的にメモリに保持することは、マシン上でリソースを共有するための最良の方法ではありません。うまく機能する簡単な解決策は、クライアントがサービスを使い始める前に、毎朝特定の時間にサービスを起動するイベントをスケジュールすることです。簡単なスクリプトまたは EXE 呼び出しを使用して、Windows タスク スケジューラでスケジュールすることができます。

于 2009-05-07T08:55:04.800 に答える
2

これを実行したい、またはベストプラクティスであると言っているわけではありませんが、十分に機能する場合があります。それはあなたが求めていたものと一致しているようです。

概要:プロセス内のすべてのページを、一度に1ページずつ定期的にタッチします。

バックグラウンドで実行され、N秒ごとに1回ウェイクアップするスレッドについてはどうでしょうか。ページがウェイクアップするたびに、アドレスXからの読み取りが試行されます。不正なアドレスを読み取った場合に備えて、例外ハンドラーによってその試行は保護されます。次に、Xをページのサイズだけインクリメントします。

4GBで65536ページ、3GBで49152ページ、2GBで32768ページあります。アイドル時間(一晩のデッドタイム)を、各ページにヒットする(試行する)頻度で割ります。

BYTE *ptr;

ptr = NULL;
while(TRUE)
{
    __try
    {
        BYTE b;

        b = *ptr;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        // ignore, some pages won't be accessible
    }

    ptr += sizeofVMPage;

    Sleep(N * 1000);
}

GetSystemInfo()から返される結果のdwPageSize値からsizeOfVMPage値を取得できます。

アプリ内の他のスレッドが同時にメモリ保護を変更している可能性があるため、if(!IsBadReadPtr(ptr))を使用して例外ハンドラーを回避しようとしないでください。このために動けなくなった場合、その理由を特定することはほとんど不可能です(再現性のない競合状態である可能性が高い)ので、時間を無駄にしないでください。

もちろん、このスレッドは日中はオフにして、デッドタイム中にのみ実行することをお勧めします。

于 2010-03-16T17:44:01.670 に答える
1

もう 1 つの確認事項は、データがローカライズされていることです。

つまり、何かを実行する前に、300 MiB のメモリすべてが本当に必要なのでしょうか? 使用するデータ構造を再編成して、特定の要求をわずか数メガバイトで満たすことができますか?

例えば

  • 300 MiB のヒープ メモリに顔認識データが含まれている場合。男性と女性の顔データを一緒に保存するようにデータを内部的に整理することはできますか? それとも大きな鼻は小さな鼻とは別のものですか?

  • ある種の論理構造を持っている場合、ソートできますか? バイナリ検索を使用して多くのページをスキップできるようにするには?

  • それが独自のメモリ内データベース エンジンである場合、メモリ ページ ヒットをあまり必要としないように、データのインデックス作成/クラスタ化を改善できますか?

  • それらが画像テクスチャの場合、一般的に使用されるテクスチャを互いに近くに配置できますか?

何かを行う前に、300 MiB のメモリすべてが本当に必要ですか? そのすべてのデータがメモリに戻されないと、リクエストを処理できませんか?


それ以外の場合: 6 ᴀᴍ にスケジュールされたタスクが起動します。

于 2010-03-16T18:15:13.440 に答える
1

3 番目のアプローチは、カウンターをインクリメントするような些細なことを行うスレッドをサービスに実行させてから、かなり長い間 (たとえば 10 秒間) スリープ状態にすることです。Thios は他のアプリケーションへの影響を最小限に抑える必要がありますが、少なくともページの一部を利用できるようにしておく必要があります。

于 2009-05-07T09:02:29.807 に答える
0

コストの面では、おそらく最も安価で簡単な解決策は、そのサーバー用に RAM を追加購入することです。その後、ページ ファイルを完全に無効にすることができます。32 ビットの Windows を実行している場合は、4 GB の RAM を購入するだけです。次に、アドレス空間全体が物理メモリでバックアップされ、ページ ファイルはとにかく何もしません。

于 2009-05-07T08:59:18.033 に答える