We have some sort of a leak, the nature of which I don't understand. Gen0/1/2 heaps do not increase in size however Working Set increases until we OOM.
DebugDiag tells me that CLR.DLL owns the increasing memory and also tells me that we have a growing finalizer queue - 100s of thousands of Texture2D (its an XNA app) objects which increase with time.. However no profiler (dotTrace, Ants, CLR Profiler) can find these objects - they don't show in the heap and CLRProfiler claims they are never allocated.
So I look in WinDbg - once again I can see a growing Finalizer queue full of Texture2D. fReachable is empty and it claims all those objects are on the heap anyway.
*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*
Then I look for those 726,000 instances so that I can find who owns them. Problem is that dumpheap says there's only 218. Thats pretty much what I expect and what the managed profilers tell me exists.
*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*
So where are the rest of the items on the finalizer queue coming from? Right now I suspect the growing finalizer queue for the memory allocations as it grows and therefore out OOM. Its as if those 218 items are being added to the Finalizer queue multiple times for some reason.
Many thanks
Andy
For completeness here's what was happening.
There's an issue with XNA that causes ReRegisterForFinalize to be called on Texture2Ds if you access the Device.Texture[] collection. Sunburn access this collection every frame to work around another XNA issue so if you have a lot of Textures then this can build up very rapidly.
There's several places in XNA (Texture3D etc) that use the same pattern so I assume you can repro this in many ways.
Since there is no sign of an XNA 5 we had to work around it - I discovered that simply calling SuppressFInalize after accessing the collection removes the extra item that had been added. We think its safe :-) The Sunburn guys are adding a fix in their code and we hope the issue will go away.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With