web-dev-qa-db-ja.com

ASP.NETアプリがメモリを消費します。アプリケーション/セッションオブジェクトの理由は?

そのため、外部企業によって開発されたASP.NETアプリケーションのストレステストを行っています。 1秒あたり約50のリクエストを実行しており、約30分後、48個のワーカープロセス(w3wp.exe)のそれぞれが最大約400MBになります。 IIS7で実行しています。

DotTraceをいじった後、ここでメモリリークがあることはかなり確信していますが、アプリケーションを知らずに100%確実にすることは困難です。私たちがこの理論に直面したとき、彼らは30秒後に「メモリは.NETで自動的に処理される」のようなことを言ってそれを却下しました。確かに、データがファイナライズされた場合、.NETは48x〜400MBのガベージコレクションを行いますか?

とにかく、私はWinFormsでの作業に慣れています。 ASP.NETでメモリリークをどの程度正確に作成しますか? .NETでアプリケーションオブジェクトとセッションオブジェクトを(誤って)使用する唯一の方法はありますか?

編集

この質問を投稿してから、リクエストハンドラー(Webサービスクラス、Webフォームなど)でオブジェクトへの静的参照を保持すると、「リーク」が発生することがわかりました。おそらくここでは正しい用語ではありませんが、とにかく... IISによる各要求の後にハンドラークラスが強制終了されて再作成されたと思ったので、これはわかりませんでした。

したがって、次のようにコーディングします。

public class SomeService : IService
{
    public static List<RequestData> _requestDataHistory = new List<RequestData>();
    public void SomeRequest(RequestData data)
    { 
        _requestDataHistory.Add(data);
    }        
}

遅かれ早かれサーバーをクラッシュさせます。たぶんこれはほとんどの人には明らかでしたが、私にはわかりませんでした:-)

ただし、staticキーワードを削除した場合に、これが問題になるかどうかはまだわかりません。 インスタンスは各リクエストの後に破棄されますか?

5
Nilzor

開発者は正しいかもしれません。 .Netの世界では、必要に応じてガベージコレクションとメモリの解放が行われます。つまりアプリケーションで使用できるメモリが十分にある場合、オペレーティングシステムがそれ以上の割り当てを許可しなくなるまで、アプリケーションはますます消費する可能性があります。それが本当に問題を引き起こさない限り、あなたはそれについて心配するべきではありません。

もちろん、アプリケーションがソケットやファイルハンドラーなどの管理されていないリソースを適切に処理しない場合は、メモリリークが発生する可能性があります。オペレーティングシステムオブジェクト(タスクマネージャーでは、ハンドルとユーザーオブジェクトの列を有効にできます)を見て、その方法を確認してください。彼らが成長します。

あなたが述べたように、アプリケーションまたはセッションオブジェクトの誤用も原因となる可能性があります。

なぜ48個のアプリケーションプール(ワーカープロセス)があるのだろうかと思います。これはやり過ぎであり、あなたはそれをまったく必要としません。

GCはプロセスごとにメモリを管理し、プロセスごとに400MBはそれほど多くありません。アプリプールの数をnrに減らします。コアの数-1、次にアプリケーションのストレステスト。その後、大きくなりすぎると、メモリリークが心配になる可能性があります。

あなたの追加情報に基づいて、はい、その場合、履歴リストは無期限に増えます。静的オブジェクトは、アプリケーションドメインごとに1回作成され、appdomainが存続するまで存続します。

一部のアプリケーションロジックを壊さないことがわかっている場合を除いて、staticキーワードを任意に削除することはお勧めしません。とにかくそのデータが収集される理由と、そのデータの用途を調査します。コードには別の問題もあります。スレッドセーフではなく、2つのリクエストが同時に着信したときの動作は定義されておらず、そのリストにデータを追加することにしました。

これはプログラミングの質問であり、管理上の質問ではないため、質問をstackoverflow.comに移動することをお勧めします。

そのコードを制御できず、本当にメモリの問題を解決したい場合は、X回のリクエストの後、またはY回を超えるメモリを取得した後にリサイクルするようにアプリプールを設定できますが、これもそうではありません本当の解決策。

2
Sunny

メモリリークは、一般的な意味で、新しい/継続的な使用/処理要件のために追加のリソースを予約しながら、未使用の(または使用されなくなった)リソースを正しく(またはまったく)解放しないコーディングロジックの否定的/予期しない結果です。リソースを正しく利用および解放するための適切な「クリーンアップ」が実施されている場合、実際の要件が必ずしも増加しない場合でも、全体的なリソースの「フットプリント」は増加し続けます。

要するに、それは、リソース管理の誤った仮定または単にそれの欠如に起因する可能性がある論理プログラミングの「乱用」に限定されません。

0
user48838