I am working on debugging an application that seems to leak memory like crazy; most of it seems due to fragmentation from pinned objects(downloaded image data in a WriteableBitmap). However, I am not intentionally using GC.Handle or anything like it. All I do is store the data in a MemoryStream
, and reference it like that.
What operations pin data in memory, that don't explicitly say so? Also, how can I find what pinned it using WinDbg?
EDIT: Per request, here is a (slightly sanitized) output of one of a !GCRoot on a System.Int32 array adjacent to a large block of free memory. This is representative of all of the large free blocks.
EDIT 2: After spending time with my new friends WinDbg and SOS, I found that WriteableBitmaps
AND MemoryStream
objects, are both 'pinned', and should be allocated carefully to prevent memory fragmentation. Read the article from the accepted answer for an explanation as to why that needs to be done.
DOMAIN(1AC72358):HANDLE(Pinned):72c12f8:Root: 174c5e20(System.Object[])->
16533060(Project.ProjectParts.PartContainer)->
167fe554(Project.ProjectParts.Part.PartActivity)->
167d21d8(Project.ProjectParts.Sprites.Graphic)->
16770f28(System.Windows.Controls.Canvas)->
16770e1c(System.Windows.Controls.Canvas)->
16770ee4(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])->
1680e778(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])->
16770f9c(System.Windows.Controls.Canvas)->
16819114(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])->
16819160(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])->
16818df4(System.Windows.Controls.Canvas)->
16818e58(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])->
16819f10(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])->
168194c4(System.Windows.Controls.Canvas)->
16819528(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])->
16819574(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])->
16819370(System.Windows.Controls.Image)->
21c82138(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])->
21c82184(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])->
168195dc(System.Windows.Media.Imaging.WriteableBitmap)->
21c7ce2c(System.Int32[])
DOMAIN(1AC72358):HANDLE(AsyncPinned):72c1dfc:Root: 166bae48(System.Threading.OverlappedData)->
1654d448(System.Threading.IOCompletionCallback)->
1654c29c(System.Net.Sockets.SocketAsyncEventArgs)->
1654bad4(System.Net.Sockets.Socket+StaticConnectAsyncState)->
1654ba40(System.Net.Sockets.SocketAsyncEventArgs)->
1654b684(System.ServiceModel.Channels.SocketConnectionInitiator+ConnectAsyncResult)->
1654b414(System.ServiceModel.Channels.ConnectionPoolHelper+EstablishConnectionAsyncResult)->
1654b3b0(System.ServiceModel.Channels.ClientFramingDuplexSessionChannel+OpenAsyncResult)->
1654b380(System.ServiceModel.Channels.CommunicationObject+OpenAsyncResult)->
1654b330(System.ServiceModel.Channels.CommunicationObject+OpenAsyncResult)->
1654b0f4(System.ServiceModel.Channels.ServiceChannel+SendAsyncResult)->
1654b070(System.ServiceModel.ClientBase`1+AsyncOperationContext[[Cassandra.Common.WCF.IAsyncWcfRequestProcessor, Cassandra.Common.Silverlight]])->
1654b05c(System.ComponentModel.AsyncOperation)->
1654b04c(Project.Common.IoC.InvokeAsyncCompletedEventRequestsArgs)->
1654afec(System.Action`1[[Project.Common.IoC.ProcessRequestsAsyncCompletedArgsEx, Project.Common.SL]])->
1654afc8(Project.Common.IoC.AsyncRequestDispatcherEx+<>c__DisplayClass1)->
1654afa0(Project.Common.IoC.NetResponseReceiver)->
1653408c(System.Action`2[[Cassandra.Common.ExceptionInfo, Cassandra.Common.Silverlight],[Cassandra.Common.ExceptionType, Cassandra.Common.Silverlight]])->
16533ffc(Project.ProjectParts.ILE.Services.EngineProxyService+<>c__DisplayClass5)->
16533fdc(System.Action`1[[Cassandra.Common.ReceivedResponses, Cassandra.Common.Silverlight]])->
16533fbc(Project.ProjectParts.ILE.Services.IEngineProxyExtensions+<>c__DisplayClass1`2[[Project.Services.RequestsAndResponses.ListMediaServersByTokenRequest, Project.Services.RequestsAndResponses.Silverlight],[Project.Services.RequestsAndResponses.ListInstitutionMediaServersResponse, Project.Services.RequestsAndResponses.Silverlight]])->
16533f9c(System.Action`1[[Project.Services.RequestsAndResponses.ListInstitutionMediaServersResponse, Project.Services.RequestsAndResponses.Silverlight]])->
1650a2a0(Project.ProjectParts.ILE.MainPage)->
1674ea0c(Project.ProjectParts.ActivityTimer)->
165330a4(Project.ProjectParts.PauseManager)->
165330bc(System.Collections.Generic.List`1[[Project.ProjectParts.IPausable, ActivityFramework]])->
166a8610(System.Object[])->
167ca858(Project.ProjectParts.ActivityTimer)->
167ca838(Project.ProjectParts.ActivityTimerEventHandler)->
16533060(Project.ProjectParts.PartContainer)->
167fe554(Project.ProjectParts.Part.PartActivity)->
167d21d8(Project.ProjectParts.Sprites.Graphic)->
16770f28(System.Windows.Controls.Canvas)->
16770e1c(System.Windows.Controls.Canvas)->
16770ee4(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])->
1680e778(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])->
16770f9c(System.Windows.Controls.Canvas)->
16819114(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])->
16819160(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])->
16818df4(System.Windows.Controls.Canvas)->
16818e58(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])->
16819f10(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])->
168194c4(System.Windows.Controls.Canvas)->
16819528(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])->
16819574(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])->
16819370(System.Windows.Controls.Image)->
21c82138(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])->
21c82184(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])->
168195dc(System.Windows.Media.Imaging.WriteableBitmap)->
21c7ce2c(System.Int32[])
DOMAIN(1AC72358):HANDLE(Pinned):72c2b18:Root: 21c7ce2c(System.Int32[])
Assuming silverlight works in the same way as the full .net framework, an object over 85k in size will pretty much never be garbage collected. http://msdn.microsoft.com/en-us/magazine/cc534993.aspx
We broke up our large queue objects into an array of smaller queues which then allowed the data structure to be collected once they had shrunk back down to normal running size. Before this code change, once the queue had grown beyond the threshold the memory would never be released back to the OS.
Could this be what you are experiencing?
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