この記事では、Microsoft ASP.NET でメモリが多い場合に確認する簡単な操作について説明します。
元の製品バージョン: ASP.NET
元の KB 番号: 893660
この記事では、いくつかの一般的な問題、これらの問題を解決するためのアクション、およびこれらの状況が問題を引き起こす可能性がある理由の簡単な説明から始めます。
ASP.NET サポート音声列
2005 年 4 月の [サポート音声] 列で、誤って間違ったファイルへのリンクが提供されました。 Web サービスのダウンロードにリンクする代わりに、Web サービスによって返される XML ファイルにリンクしました。 そのリンクは修正されました。 正しいファイルが添付された記事を確認する場合は、XMLHTTP を使用した Dynamic ページの更新を参照してください。
高メモリと見なされる内容
明らかに、この質問は、特定のアプリケーションのボリュームとアクティビティによって異なります。 一般に、高いメモリは、ASP.NET ワーカー プロセス (Aspnet_wp.exe) または インターネット インフォメーション サービス (IIS) ワーカー プロセス (W3wp.exe) メモリが一貫して増加しており、快適なレベルに戻っていない場合です。
一般に、既定の 2 GB のユーザー メモリ アドレス空間では、快適なレベルは 600 MB 未満になります。 メモリ レベルがその快適なレベルより高くなると、必要以上に少なくなります。 この動作は、システムで実行されている他のアプリケーションに影響する可能性があります。
重要なのは、一部のアプリケーションが他のアプリケーションよりも多くのメモリを必要とすることを理解することです。 これらの制限を超えている場合は、メモリを追加したり、Web ファームに別のサーバーを追加したりできます (または、Web ファームを検討してください)。 このような場合は、プロファイリングも推奨されます。 これにより、開発者はより無駄のないアプリケーションを作成できます。 この記事では、サーバーの実行が停止するまでメモリの増加が一貫して発生する状況について説明します。
デバッグ用にアプリケーションを設定する
ここに表示されるメモリが多い理由の 1 つは、アプリケーションのデバッグ、トレース、またはその両方が有効になっている場合です。 アプリケーションを開発するときは、デバッグとトレースを有効にする必要があります。 既定では、Visual Studio .NET でアプリケーションを作成すると、 Web.config ファイルに次の属性が設定されます。
<compilation
...
debug="true"
/>
または
<trace
enabled="true"
...
/>
また、アプリケーションの最終的なビルドを行うときは、デバッグ モードではなくリリース モードで実行してください。 運用環境に入ると、デバッグは不要になります。 それはあなたのパフォーマンスを本当に遅くし、あなたの記憶を食べる可能性があります。 この属性を設定すると、アプリケーションの処理方法に関するいくつかの変更が行われます。
まず、この compilation
要素で設定されている場合でも、バッチ コンパイルは無効になります。 つまり、アプリケーションに分割できるように、アプリケーション内のすべてのページに対してアセンブリを作成します。 これらのアセンブリはメモリ領域全体にランダムに分散できるため、メモリを割り当てる連続した領域を見つけるのが困難になります。
次に、 executionTimeout
属性 (<httpRuntime> Element) が高い数値に設定され、既定値の 90 秒がオーバーライドされます。 コードを忍耐強くステップ実行して失敗を見つける間はアプリケーションをタイムアウトにできないため、デバッグ時には問題ありません。 ただし、運用環境では重大なリスクです。 これは、何らかの理由で不正な要求がある場合、スレッドに保持され、数分間ではなく何日間も有害な動作を続けるということです。
最後に、 Temporary ASP.NET files フォルダーにさらにファイルを作成します。 また、生成されたすべてのコードに System.Diagnostics.DebuggableAttribute
(System.Diagnostics 名前空間 が追加されるため、パフォーマンスが低下する可能性があります。
この記事から他に何も得ない場合は、この情報を取得することを願っています。 デバッグを有効のままにすると、問題が発生します。 この動作はあまりにも頻繁に見られ、変更が非常に簡単です。 ページ レベルで設定できることに注意してください。 すべてのページで設定されていないことを確認します。
文字列連結
サーバー側のコードを使用し、ブラウザーに送信する 1 つの大きな HTML 文字列をビルドするだけで HTML 出力を構築するアプリケーションがあります。 問題ありませんが、 +
と &
連結を使用して文字列を構築している場合は、構築している大きな文字列の数がわからない可能性があります。 例えば次が挙げられます。
string mystring = "<html>";
mystring = mystring + "<table><tr><td>";
mystring = mystring + "First Cell";
mystring = mystring + "</td></tr></table>";
mystring = mystring + "</html>";
このコードは十分無害に見えますが、メモリに格納しているものは次のとおりです。
<html>
<html><table><tr><td>
<html><table><tr><td>First Cell
<html><table><tr><td>First Cell</td></tr></table>
<html><table><tr><td>First Cell</td></tr></table></html>
最後の行だけを格納しているが、これらの行のすべて格納していると思われる場合があります。 特に大きなテーブルを構築する場合は、大きなレコードセットをループして、それがどのように手に入らないかを確認できます。 あなたがやっていることであれば、 System.Text.StringBuilder
クラスを使用して、1つの大きな文字列を格納するだけです。 「 Visual C# を使用して文字列連結のパフォーマンスを向上させる」を参照してください
.NET Framework Service Pack 1 (SP1)
.NET Framework SP1 をまだ実行していない場合は、メモリの問題が発生している場合は、この SP をインストールします。 私は詳しく説明しませんが、基本的にSP1ではメモリをより効率的に割り当てていきます。 基本的には、一度に 64 MB ではなく、一度に 16 MB を大きなオブジェクトに割り当てることになります。 私たちは皆移動しました、そして、我々はいくつかの大きな箱ではなく、多くの小さな箱を使用している場合、私たちは車やトラックにもっと多くを詰めることができることを知っています。 ここでのアイデアです。
定期的にリサイクルすることを恐れない
既定では、IIS のアプリケーション プールは 29 時間ごとにリサイクルされます。 Aspnet_wp.exe プロセスは、タスクの終了、IIS の再起動、またはコンピューターの再起動まで継続します。 この動作は、このプロセスが数か月間実行される可能性があることを意味します。 一部のアプリケーションでは、数日おきに便利なタイミングでワーカー プロセスを再起動することをお勧めします。
確認事項
以前は、迅速に修正できるすべてのものでした。 ただし、メモリの問題が発生している場合は、次の質問を自問してください。
多数のラージ オブジェクトを使用していますか? 85,000 KB を超えるサイズのオブジェクト ヒープに格納されます。
セッション状態でオブジェクトを格納していますか? これらのオブジェクトは、使用して破棄する場合よりもはるかに長くメモリに残ります。
Cache
オブジェクトを使用していますか? 賢く使用すると、パフォーマンスに大きなメリットがあります。 しかし、それが無意味に使用されると、解放されない多くのメモリが使用されます。Web アプリケーションの
recordsets
が大きすぎますか? Web ページで 1,000 件のレコードを検索する必要はありません。 1 回の乗車で 50 ~ 100 件を超えるレコードを取得しないように、アプリケーションを設計する必要があります。
デバッグ
WinDbg の設定には入りません。 ただし、より複雑な問題をトラブルシューティングする場合は、次のコマンドを使用して、メモリ内の正確な内容を確認できます。
!eeheap -gc
このコマンドを実行すると、マネージド メモリの量が表示されます。 この値が大きい場合は、マネージド コードでビルドしているものがあります。
!dumpheap -stat
メモリが大きい場合でも、このコマンドの実行にはかなりの時間がかかります。 ただし、このコマンドを実行すると、すべてのオブジェクトの一覧、各型の数、各オブジェクトが使用しているメモリの量が表示されます。 (たとえば、 StringBuilder
クラスの場合、多くの System.String
オブジェクトが表示されます)
オブジェクトが多くのメモリを取っているのを見つけたら、次のコマンドを使用してさらに掘り下げてみます。
!do <addr>
探しているオブジェクトのアドレスは、 dumpheap
コマンドで取得できます。
これらの列の特定の状況に対してこの診断ツールを使用する方法をさらに組み込もうとします。 良い仕事をしている場合は、お知らせください。