15

ここで、私たちの Web アプリで厄介な問題が発生します。(Asp.net 2.0 Win サーバー 2008)

ウェブサイトのメモリ使用量は、かなり静的なレベルにとどまると予想されますが、どんどん増えていきます。(状態に保存される少量のデータがあります)。

問題が何であるかを知りたくて、私は System.GC.Collect(); を実行しました。数回、メモリ ダンプを取得し、このメモリ ダンプを WinDbg にロードしました。

DumpHeap -Stat を実行すると、メモリ内にぶら下がっている特定のタイプの数値が異常に大きくなります。

0000064280580b40 713471 79908752 支払いオプション

したがって、この型に対して DumpHeap -MT を実行すると、オブジェクト参照のスタックが得られます。これらのランダムな数を選択して !gcroot を実行すると、コマンドが戻ってきて、参照が保持されていないことが報告されます。

私には、GC がこれらのアイテムを収集するのはまさにこのときですが、何らかの理由で未処理のままになっています。

何が起こっているのか説明できる人はいますか?

4

7 に答える 7

5

Windbgでsosex.dllを使用してみてください。これは、.NETデバッグを支援するために作成された拡張機能です。!gcrootに似た!refsという名前のコマンドがあり、オブジェクトを参照しているすべてのオブジェクトが表示され、さらに、それも参照しているすべてのオブジェクトが表示されます。

著者のWebサイトの例では、!refsがオブジェクトに対して使用されており、出力は次のようになります。

0:000> !refs 0000000080000db8
Objects referenced by 0000000080000db8 (System.Threading.Mutex):
0000000080000ef0         32    Microsoft.Win32.SafeHandles.SafeWaitHandle 

Objects referencing 0000000080000db8 (System.Threading.Mutex):
0000000080000e08         72    System.Threading.Mutex+<>c__DisplayClass3
0000000080000e50         64    System.Runtime.CompilerServices.RuntimeHelpers+CleanupCode
于 2009-03-08T20:56:50.200 に答える
2

ひょっとして PaymentObject はファイナライザーを実装していますか? STA COM オブジェクトを呼び出しますか?

!finalizequeue の出力を見て、ヒープに表示されているオブジェクトの数が、ファイナライズを待っている可能性のあるオブジェクトの数とほぼ同じかどうかを確認したいと思います。出力はおそらく次のようになります。

generation 0 has 57 finalizable objects (0409b5cc->0409b6b0)
generation 1 has 55 finalizable objects (0409b4f0->0409b5cc)
generation 2 has 0 finalizable objects (0409b4f0->0409b4f0)
Ready for finalization 0 objects (0409b6b0->0409b6b0)

Ready for finalizationオブジェクトの数が増え続け、特定のガベージ コレクションが発生している場合 (perfmon カウンターで確認)、ファイナライザー スレッドがブロックされている可能性があります。確認のために、プロセスの存続期間中 (リサイクル前) に複数のスナップショットを作成する必要がある場合があります。サイトに何らかの負荷がかかっている限り、私は通常、マジック ナンバー 3 に頼っています。

ファイナライザーのバグにより、ファイナライザー スレッドがブロックされ、オブジェクトが収集されなくなる可能性があります。

PaymentOption オブジェクトが従来の STA COM オブジェクトを呼び出す場合、STA コンポーネントによって引き起こされるこの記事の ASP.NET ハングおよび OutOfMemory 例外は、正しい方向を指している可能性があります。

于 2009-08-14T05:04:08.597 に答える
1

私は同じ問題を自分で調査していて、参照のないオブジェクトが収集されなかった理由を尋ねていました。

85,000バイトを超えるオブジェクトは、メモリが解放される頻度が少ないラージオブジェクトヒープに格納されます。

http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

単一のPaymentOptionはそれほど大きくないかもしれませんが、それらはコレクション内に含まれていますか、それともDataSetのようなものに基づいていますか?PaymentOption / collection / DataSetのいくつかのインスタンスを選択してから、sos!objsizeコマンドを使用してそれらのサイズを確認する必要があります。

残念ながら、これは実際には質問に答えません。.netフレームワークを信頼して、必要なときにいつでも未使用のメモリを解放できると思います。ただし、サーバー上でメモリが非常にタイトに見える場合でも、私が見ているアプリを実行しているワーカープロセスによって大量のメモリが使用されていることがわかります。

于 2009-07-28T10:15:12.870 に答える
1

アプリケーションに関する詳細情報がないわけではありません。しかし、私たちはずっと前にいくつかの厄介なメモリの問題に遭遇しました. ASP.NET キャッシュを使用していますか? Raymond Chen がよく言うように、「貧弱なキャッシュ戦略はメモリ リークと見分けがつきません」。

別のツールである CLRProfiler.exe を確認してください。これは、オブジェクト参照ツリーを走査して、オブジェクトがどこにルートされているかを確認するのに役立ちます。これもいいです:リンクテキスト

これは聞いたことがあるでしょう - GC.Collect をしなければならないのなら、何かがおかしいのです。

于 2009-03-02T19:24:18.457 に答える
1

非同期処理で作成された PaymentOption オブジェクトですか? EndInvoke を呼び出さないと、このような問題が発生する可能性があることを覚えています。

于 2009-03-02T19:26:05.630 に答える
0

参考までに、.NET 4 の SOS は、役立つ可能性のあるいくつかの新しいコマンドをサポートしています。つまり、!gcwhere(異議の生成を見つける; sosex の gcgen) および!findroots(缶に書かれていることを実行します; sosex の !refs)

どちらもSOS のドキュメント記載されており、Tess Ferrandez のブログで言及されています。

于 2010-03-01T21:40:49.173 に答える