web-dev-qa-db-ja.com

IIS7.5アプリプールのリサイクル-.Net OutOfMemoryException

IIS/Windows 2008 R2の.Net OutOfMemoryExceptionsがヒットしたアプリケーションのランダムなページにスローされるという奇妙な状況。

同じ.Netアプリケーション(サイトごとに異なるコードベースフォルダーとアプリプール)である約1000の個別のサイトがあります。 64ビットWindowsで.Net 2.0を実行しているアプリケーションは、「AnyCPU」フラグでコンパイルされています。

同じ正確なコードが古いサーバーで機能し、outofmemoryexceptionsをスローしないためアプリケーションのプロファイリングとダンプの調査、および大きなオブジェクトヒープの断片化を回避するのに役立つコードの最適化の実行に多大な時間を費やすことを控えています(したがってコードベースを調べて最適化するだけではなく、原因となる可能性のあるサーバー構成の問題に関するヒントを得たいと考えています...)。

構成1-Rackspace CloudSites(共有ホスティング、FTPのみが可能、それにアクセスできませんIIS設定):

1 IISサーバー、それを管理することはできませんが、各アプリプールには250MBのリサイクル制限があると言われました。1000のサイトのうち、多くのサイト(20-50ish)は明らかに同じものを共有していますアプリプール。ここではOutOfMemoryExceptionsを取得することはなく、何年にもわたってアプリケーションが実行されています。

構成2-ラックスペース専用サーバー(フルコントロール):

128 GB RAMを備えたモンスターサーバー、専用、各サイトには独自のアプリプールがあります。すべてのアプリプールの設定は同じです(350MBのリサイクル制限)。これが結果であるかどうかはわかりませんが、このサーバーのページファイルサイズは4 GBです(構成1の内容がわからない-これを増やす/対処する必要がありますか?)。

どちらの構成も2つまたは3つのWebサーバー間で負荷分散されますが、トラフィックが発生していないサイトを検索しているため、OutOfMemoryExceptionsで強制終了されるため、これ自体は問題ではありません。

5
Code Monkey

この記事は私が書いている間にエスカレートしました、ここに持ち帰りの弾丸があります

TL; DR

  1. ページファイルのサイズを大きくします(私が言うヒップから少なくとも40 GBに増やしますが、ディスク容量とI/Oを余裕があればもっと多くできますが、下部の記事を読んでください)。
  2. frequentHitThresholdfrequentHitTimePeriod の値を増やします(Webサービスキャッシュのパフォーマンスカウンターを確認し、それに応じて調整します)。
  3. ラージオブジェクトヒープのキャッシュエントリを回避するには、 maxResponseSize 値を85KB以下に下げます。
  4. アプリケーションプールのリサイクルのメモリ制限を下げます。あまり意味がありません。
  5. 同じまたは類似したコードベースを持つアプリケーションをアプリケーションプールにグループ化することを検討してください。

元の回答

これが結果であるかどうかはわかりませんが、このサーバーのページファイルサイズは4 GBです(構成1の内容がわからない-これを増やす/対処する必要がありますか?

これ、ここ^すぐここ^見てください。

これが、アプリケーションがOutOfMemoryExceptionをスローする理由であり、最もランダムで良性のように見えるリクエストに応答する理由ですが、その理由を理解するために、次の1つを明確にしてみましょう。

OutOfMemoryは、サーバーのメモリが不足しているという意味ではありません。

悪い冗談のように聞こえますが、実際はそうではありません。 それはオペレーティングシステムがメモリの枯渇について不平を言っているのではなく、それがプロセスです。
最後のステートメントが意味をなさない場合は、読み進めてください。

メモリ管理101

プロセスがOSからメモリを割り当てるとき、それはpagesと呼ばれるフラグメントのシーケンスになり、1ピースは4キロバイトで、プロセスはそれ自身のものとして扱うことができます(これは一般的に呼ばれます)仮想アドレス空間として)。

オブジェクト(文字列、XMLドキュメント、画像など、メモリに保持する必要があるもの)は4KBのページサイズを超える可能性があるため、プロセスはこのメモリから連続して複数のページを割り当てる必要がある場合があります。

ただし、時間の経過とともに、.NET CLRを使用していても、メモリ空間が断片化します。ガベージコレクターは、コレクション中にワーキングセット内のページを再配置することで、アプリケーションがアドレス空間をより有効に利用できるように試行し、実行します(これは実質的にディスクのデフラグと同じです)が、ラージオブジェクトヒープへのポインターたとえば、そのままになります。

IIS 7.xが役割を果たす方法

最近のように この回答で説明されています 、IISは、キャッシュ可能な出力オブジェクト(最大256KBの静的ファイルなど)も同じようにできるだけ多く保存しようとしますアプリケーションにサービスを提供するプロセス-その回答の提案に加えて、 <serverRuntime> 構成要素を使用してキャッシュ頻度のしきい値を調整することもできます。

いずれの場合でも、IIS 7.5-デフォルトの構成では-ワーカープロセスに十分なメモリを割り当てることに細心の注意を払っており、 "トラフィックなし"であっても、ワーカープロセスがクレームを要求することは珍しくありません。ディスク上にわずかに小さいアプリケーションコードベースがある場合でも、起動時に最初の100MB。

これはページファイルと何が関係していますか?

100MB * 1000プロセスは、128GBのRAM OSが提供しなければならないものではありません。IIS =ワーカープロセスに必要なだけのメモリを割り当てようとします。ある時点で停止し、オペレーティングシステム用に、インストールされているメモリの合計の約85%で空き容量を残します。RAM可能性があります(これは私がドキュメントを見たことはありませんが、IISさまざまなハードウェア仕様でのインストール)の実地経験から引き出されたものです)。

この時点で、オペレーティングシステムは、代わりにページファイルからページを割り当てることにより、メモリの解放を支援できます。ページは、物理ディスク上のファイルに保存されます。ディスク容量は多くの場合十分であるため、ディスクストレージの大きなチャンクを割り当てることはそれほど大きな問題ではありませんが、1000プロセスのメモリをページングする必要があり、4GBのスペースでのみそれが許可されている場合は、それほど時間がかかりませんプロセスは、断片化されていないメモリのより長いシーケンスとpuff!を割り当てることができません:プロセスはOutOfMemoryExceptionをスローします。これは単に、アクセス可能な仮想アドレス空間で何かのために十分な隣接ページを見つけることができなかったことを意味します。

大きなオブジェクトである必要はありません。それらは、実行時に利用できる連続したページの最大数よりも大きい必要があります。理論的には、現在サイズが2KBを超える文字列に単一の文字を追加しようとすると、OutOfMemory例外が発生する可能性があります。

ページファイルのサイズは何に設定する必要がありますか?

この質問に対するMicrosoftの回答は常に「依存します」ですが、少なくとも1 x RAM + 257MB(これは、完全なメモリダンプを書き込むためにシステムが必要とするストレージの量です) )。

経験則は1.5〜2 x RAM=のようですが、これも場合によって異なります。適切な最小および最大のページファイルサイズを決定する方法について、多くの記事が公開されています。特定のシステムで最も関連性の高いものを下部に含めました。

ページファイルを含むディスクも必ず監視してください。ディスクキューの長さのカウンターが急上昇した場合は、専用のディスクに移動したり、複数のディスクに分散したりできます。

64ビットバージョンのWindowsに適切なページファイルサイズを決定する方法

9

アプリケーションプールのメモリ制限を無効にして(0に設定)、アプリケーションプールが必要なだけすぐに使用できるようにすることができます。ただし、何かがリークしているようで、最終的には使用可能なすべてのメモリを消費します(そして、アプリプールを再びリサイクルします)。

c:\windows\system32\LogFiles\HTTPERRログファイルで致命的なエラーメッセージを確認してください。

PageFile設定を変更する必要はありません。これは、128GBのRAMが空になった場合にのみ使用されます。

メモリリークの原因を追跡するには、トレースログまたはDebugDiagでさらに掘り下げる必要があります(最も簡単なタスクではありません)。

IISデバッグ診断ツールを使用してIISプロセス)でメモリリークをトラブルシューティングする方法

IIS 7.xアプリケーションプール)でのネイティブメモリリークのトラブルシューティング

1
Brock Hensley

この問題は、1000以上のアプリプールをデフォルトの64ビットではなく32ビットモードに切り替えることで解決されました。これを確認するには、64ビットに戻し、メモリ不足の例外をすぐに確認しました。

ページファイルでのジェッセンのポイントには重みがあると思います。 。 。ページファイルの更新にはシステムの再起動が必要だったので、32ビットモードのアプリプールに切り替えようとしました(再起動の必要はありません)。

誰かがこれについて興味深いコメントを持っている場合は、お気軽に!

ありがとう!

0
Code Monkey