
当社では 2 台のサーバー (IIS8 および 10) で IIS を実行しており、最近、主に aspx ページ経由でアクセスされる ASP.NET WebForms アプリケーションのメモリ使用量が非常に高くなっています。
時間の経過とともに、アプリケーション プールがメモリをどんどん消費し、サーバーの物理メモリ (64 GB) がほぼ使い果たされることになります。これは明らかに正常ではありません。
なぜこのようなことが起こるのか調べてみましたが、わかりません。これがアプリケーションのメモリ リークなのか、通常の動作なのかは不明ですが、おそらく誰かが解明してくれるでしょう。
事実:
時間が経つにつれて、アプリケーション プールは解放されないメモリをどんどん予約して使用します (タスク マネージャーによると、ワーキング セットとコミット サイズの両方が非常に大きいため、実際に使用/保持されているということですね)。
ANTS、.dotMemory、.NET MemoryProfiler などのメモリ プロファイラーは、管理対象メモリの消費量が 20 ~ 200 MB とかなり低く、使用されているが空いている管理対象外メモリが大量にあることを示しています。
スナップショットや詳細なプロファイリング方法を使用しても、管理されていない使用の原因が何であるかについてのヒントは得られません。
F5 キーを離さずにスタート ページを「ハンマーで叩く」と、1 分間にメモリ使用量が 2 ~ 5 GB まで急増する可能性があります。これは少々異常です。
IIS/アプリケーション プールは、利用可能なメモリが増えると、便宜的にメモリを予約する傾向があることはわかっていますが、これは多すぎます。
唯一わかるのは、フロント ページがコントロールと ComponentModel オブジェクトとともにメモリ内に保持されているように見えることですが、メモリ プロファイラーのどこにもページ オブジェクトまたは独自の名前空間クラスへの参照は 1 つもありません。
1 年前はメモリ消費量は概ね良好で、合計 2 ~ 3 ギガバイトで止まっていましたが、アプリケーションの古いバージョンではこれを再現できなくなりました。
WIN10 での IIS の新規ローカル インストールでも発生します。
アプリケーションはリリース モードで構築され、最適化され、現在単一の DLL にコンパイルされています。トレース フラグをオンにして試しても、サイズは 5 MB です。
アプリケーションを分解して、いくつかのモジュールに分割し、それらの動作を確認する必要があるようです。実行時に読み込まれるアセンブリ/ライブラリが問題になる可能性はありますが、問題になるべきではありません。実際にはそれほど多くのもの (FreeTextBox、Microsoft ReportViewer、SharpCompress、Crystal Reports、AjaxControlToolKit 15) を参照していません。何が起こるかを確認するために、CrystalReports/AjaxControlToolKit 以外のすべてを削除しましたが、変更は行っていません。
また、タイマーや UpdatePanel などの WebForms コントロールも多数使用することがあります。
また、.NET クラス インスタンスが何へのリンクも表示しないため、1 つ以上の aspx ページがメモリ内に保持される原因となる隠し参照があると想定して、メモリプロファイラーを使用して原因を特定する方法もわかりません。
メモリ予約に関して誤解している点や、このメモリ消費の問題をトラブルシューティングする方法など、どのようなヒントでもいただければ幸いです。
貴重なお時間をいただきありがとうございました!
編集 (言い忘れました): - スタート ページの Page_Load 関数に GC.Collect/WaitForPendingFinalizers/GC.Collect を追加して、効果があるかどうかを確認しました。確かに、しばらくは効果がありましたが、別のプレッシャー状況 (F5 を使用) が発生して、メモリ使用量が再び極端に増加しました。
答え1
GC.WaitForPendingFinalizers が役立つ場合、それはスレッドによって使用されているメモリの兆候である可能性があります。page_load で新しい別のスレッドを開始すると、大量のメモリが使用される可能性があります。タスク マネージャーでスレッドの数を確認して、問題の診断を開始します。