What can "Pin" an object in memory in Silverlight?
Asked Answered
H

2

7

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[])
Horribly answered 8/8, 2011 at 23:34 Comment(5)
you might want to google for "writablebitmap memory leak" I remember reading about it some time ago.Brewhouse
I have seen those; and they all seem to be different cases than mine, or have been sixes since SL3.Horribly
Can you run !gcroot <my_object_pointer> against the object you think got pinned and add this to your question?Prole
I sure can once I get back to that computer - and its not just one object. At its worst, its ~14,000 System.Int32[] arrays.Horribly
In my case, it appears that the aforementioned leak is yet another UserControl leak; and will be fixed in the upcoming SL5 release. However, I am still curious as to what structures use pins to hold memory in place.Horribly
S
1

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?

Serenaserenade answered 16/8, 2011 at 10:40 Comment(1)
Thanks for that article! It is very interesting. We did have some issues with that, especially when some very tiny images were fragmenting the LOH terribly. Re-arranging how those were allocated cleared things up nicely. Using a .NET Memory Profiler, I found that 450 MB if the memory leak data is being lost to "Unknown Unmanaged Heaps", with very cryptic and frankly unhelpful stack traces. Answer accepted because the article addresses the core principles of some of the reason I was leaking - the other part of the leak is a bug in SL4.Horribly
H
0

Pin is mechanism to hold Async or handlers in your controls to be "do not relocated in memory" while the operation is in progress or handler reference exists.

You should also check whether you have any handlers or Async operations such as WCF client or Http Web Service client open state, prior to leaving the control or view model or model. If any object is pinned when you exit the control, view model or model you will have memory leak for those.

Also keep in mind that if those object ends up to be more than 85.000bytes they end up to be in generation 2 which is not Garbage Collected until the application (domain) terminates.

If object is smaller than 85K and survives the GC for Generation 0. Its promoted to Generation 1, and when survive or is not released or something is holding its will be end its life to Generation 2, which in SL is not collected.

Also to note: if you release/allocate frequently those object will cause the memory to be fragmented. If your program requires to have continuous space in memory and there is no free block that big because of the fragmentation you will get out of memory exception.

Hope above helps.

Haemophiliac answered 8/4, 2015 at 11:0 Comment(1)
Hi Alexander, does this answer any of the the questions (1) "What can “Pin” an object in memory in Silverlight?", (2) "What operations pin data in memory, that don't explicitly say so?", or (3) "how can I find what pinned it using WinDbg?"Denticulation

© 2022 - 2024 — McMap. All rights reserved.