2011-08-08 13 views
7

Estoy trabajando en la depuración de una aplicación que parece perder memoria como una locura; la mayor parte parece debido a la fragmentación de objetos anclados (datos de imagen descargados en un WriteableBitmap). Sin embargo, no estoy usando intencionadamente GC.Handle ni nada parecido. Todo lo que hago es almacenar los datos en un MemoryStream, y hacer referencia de esa manera.¿Qué puede "Pin" un objeto en la memoria en Silverlight?

¿Qué operaciones anotan los datos en la memoria, que no lo dicen explícitamente? Además, ¿cómo puedo encontrar lo que se fijó con WinDbg?

EDIT: Por la petición, aquí es una (ligeramente desinfectado) de salida de uno de un gcroot en una matriz de System.Int32 adyacente a un gran bloque de memoria libre!. Esto es representativo de todos los grandes bloques libres.

EDIT 2: Después de pasar tiempo con mis nuevos amigos WinDbg y SOS, encontré que WriteableBitmaps Y MemoryStream objetos, son a la vez 'cubrió', y deben asignarse con cuidado para evitar la fragmentación de memoria. Lea el artículo de la respuesta aceptada para obtener una explicación de por qué es necesario hacerlo.

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[]) 
+0

es posible que desee google para "fuga de memoria writeablebitmap" Recuerdo haber leído sobre ello hace algún tiempo. – Denis

+0

He visto esos; y todos parecen ser casos diferentes a los míos, o han sido seis desde SL3. –

+0

¿Puedes ejecutar '! Gcroot ' contra el objeto que crees que quedó fijado y agregarlo a tu pregunta? –

Respuesta

1

Suponiendo obras de Silverlight en la misma forma que el marco .NET completo, un objeto más de 85k de tamaño será más o menos no se recoge la basura. http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

Rompimos nuestros objetos de cola grandes en una serie de colas más pequeñas que luego permitían que la estructura de datos se recogiera una vez que se habían reducido al tamaño de ejecución normal. Antes de que este código cambiara, una vez que la cola había crecido más allá del umbral, la memoria nunca volvería a liberarse en el sistema operativo.

¿Podría ser esto lo que estás experimentando?

+0

¡Gracias por ese artículo! Es muy interesante. Tuvimos algunos problemas con eso, especialmente cuando algunas imágenes muy pequeñas estaban fragmentando el LOH terriblemente. Reorganizar cómo se asignaron las cosas despejó las cosas bien. Usando un .NET Memory Profiler, encontré que 450 MB si los datos de fuga de memoria se pierden a "Montones desconocidos no administrados", con rastreos de pila muy crípticos y francamente poco útiles. Se aceptó la respuesta porque el artículo aborda los principios básicos de algunos de los motivos por los que estaba filtrando: la otra parte de la fuga es un error en SL4. –

0

El pin es un mecanismo para mantener Async o controladores en sus controles para que "no se reubiquen en la memoria" mientras la operación está en progreso o existe una referencia del manejador.

También debe comprobar si tiene controladores o operaciones Async como el cliente WCF o el estado abierto del cliente del servicio web Http, antes de abandonar el control o ver el modelo o modelo. Si algún objeto queda anclado al salir del control, ver modelo o modelo tendrá una pérdida de memoria para ellos.

También tenga en cuenta que si esos objetos terminan siendo más de 85,000bytes terminan en la generación 2 que no es basura recolectada hasta que la aplicación (dominio) finaliza.

Si el objeto es más pequeño que 85K y sobrevive el GC para la Generación 0. Su promoción a la Generación 1, y cuando sobrevive o no se libera o algo está reteniendo terminará su vida a la Generación 2, que en SL no es recogido.

También para tener en cuenta: si suelta/asigna frecuentemente esos objetos, la memoria se fragmentará. Si su programa requiere tener espacio continuo en la memoria y no hay un bloque libre tan grande debido a la fragmentación, saldrá de la excepción de memoria.

Hope above helps.

+1

Hola Alexander, responde esto a cualquiera de las preguntas ** (1) ** "* ¿Qué puede" Pin "un objeto en memoria en Silverlight? *", ** (2) ** "* ¿Qué operaciones pin datos en memoria, que no lo dice explícitamente? * ", o ** (3) **" * ¿cómo puedo encontrar lo que se fijó usando WinDbg? * " –

Cuestiones relacionadas