5

ある種のリークがありますが、その性質はわかりません。Gen0 / 1/2ヒープのサイズは増加しませんが、ワーキングセットはOOMするまで増加します。

DebugDiagは、CLR.DLLが増加するメモリを所有していること、およびファイナライザーキューが増加していることを示しています-時間とともに増加する数十万のTexture2D(XNAアプリ)オブジェクト。ただし、プロファイラー(dotTrace、Ants、CLR)はありません。 Profiler)はこれらのオブジェクトを見つけることができます-それらはヒープに表示されず、CLRProfilerはそれらが決して割り当てられないと主張します。

そこで、WinDbgを調べます。もう一度、Texture2Dでいっぱいのファイナライザーキューが増えているのがわかります。fReachableは空であり、とにかくそれらすべてのオブジェクトがヒープ上にあると主張します。

*0:038> !finalizequeue
SyncBlocks to be cleaned up: 0
MTA Interfaces to be released: 0
STA Interfaces to be released: 0
----------------------------------
generation 0 has 1881 finalizable objects (33e365b0->33e38314)
generation 1 has 41580 finalizable objects (33e0dc00->33e365b0)
generation 2 has 685816 finalizable objects (33b70020->33e0dc00)
Ready for finalization 0 objects (33e38314->33e38314)
      MT    Count    TotalSize Class Name
......snip......
00ce67e0   726827     49424236 Microsoft.Xna.Framework.Graphics.Texture2D*

次に、726,000のインスタンスを探して、誰がそれらを所有しているかを確認します。問題は、dumpheapが218しかないことを示していることです。それは私が期待していることであり、マネージドプロファイラーが私に言っていることは存在します。

*0:038> !dumpheap -stat -type Microsoft.Xna.Framework.Graphics.Texture2D
total 0 objects
Statistics:
      MT    Count    TotalSize Class Name
00ce67e0      218        14824 Microsoft.Xna.Framework.Graphics.Texture2D
Total 218 objects*

では、ファイナライザーキューの残りのアイテムはどこから来ているのでしょうか?今のところ、メモリ割り当てのファイナライザキューが大きくなり、したがってOOMが大きくなるのではないかと思います。なんらかの理由で、これらの218個のアイテムがファイナライザーキューに複数回追加されているかのようです。

どうもありがとう

アンディ

4

2 に答える 2

2

完全を期すために、ここで何が起こっていたかを説明します。

XNAに問題があり、Device.Texture []コレクションにアクセスすると、Texture2DでReRegisterForFinalizeが呼び出されます。Sunburnは、フレームごとにこのコレクションにアクセスして、別のXNAの問題を回避します。そのため、テクスチャがたくさんある場合、これは非常に急速に蓄積される可能性があります。

XNAには同じパターンを使用する場所がいくつかあるので(Texture3Dなど)、これをさまざまな方法で再現できると思います。

XNA 5の兆候がないため、回避する必要がありました。コレクションにアクセスした後にSuppressFInalizeを呼び出すだけで、追加された余分なアイテムが削除されることがわかりました。安全だと思います:-)Sunburnの人たちはコードに修正を追加しており、問題がなくなることを願っています。

于 2012-07-25T14:28:51.797 に答える
1

ファイナライズキューに再追加されるのと同じインスタンスでしょうか?Object.Finalizeのドキュメントから:

Finalizeは、GC.ReRegisterForFinalizeやGC.SuppressFinalizeなどのメカニズムを使用してオブジェクトが再登録されていない限り、特定のインスタンスで1回だけ自動的に呼び出されます。

それはあなたがここで見ているものに合うように思われる唯一の説明です。ただし、ファイナライズのために再登録される理由はわかりません。

于 2012-07-21T08:50:42.930 に答える