2009-06-10 15 views
7

Tengo una aplicación WPF que, entre otras cosas, muestra una gran cantidad de imágenes, grandes y pequeñas. Mi problema es que la aplicación usa mucha memoria y no sé de dónde viene.¿A dónde fue mi memoria? Conteo de bytes privados grandes

El escenario, cuando haciendo hincapié en la aplicación de algunos que consiguen este gráfico de Monitor de rendimiento:

http://www.imagechicken.com/uploads/1244548604007097000.jpg

La gran línea de negro es Proceso \ bytes privados y las otras líneas son los contadores de CLR MEM (el rosa es total bytes comprometidos)

en números en el gráfico son:
bytes privados ~ 350 Mb
bytes asignados ~ 100 Mb

he estado cavando alrededor de un lote con WinDbg y otras herramientas, y todos ellos informan de que el pila administrada se comporta (pila! Informes eeheap total gestionado alrededor de 100 Mb)

He estado hurgando con aplicaciones como LeakDiag, LDGrapher pero no encontró nada.

Entonces, finalmente a mi pregunta, ¿cómo procedo para saber hacia dónde va mi memoria?

Incluso al solo iniciar la aplicación se usan 100Mb en bytes comprometidos pero 190Mb en bytes privados.

Referencias:

He leído mucho acerca de esto, entre otros en los grandes sitios:

Tess Ferrandez: http://blogs.msdn.com/tess/archive/2009/02/27/net-memory-leak-reader-email-are-you-really-leaking-net-memory.aspx

Rico Mariani: http://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx

MSDN mag: http://msdn.microsoft.com/en-us/magazine/cc163528.aspx

+0

Gracias por las respuestas hasta ahora. Por lo tanto, para aclarar,! Eeheap,! Dumpheap, gcroot etc. todos informan de las cosas que componen los 100Mb, de lo que estoy tratando de deshacerme es de la otra memoria, los 250 MB adicionales. – andyhammar

+0

Actualización - con VADUMP: Informes "Gran conjunto de trabajo total" de 236 Mb, "Otros datos" como 196 Mb. ¡Mientras tanto! Eeheap informa "tamaño del montón de GC" en 107336836. ¿Cuál es esta diferencia? – andyhammar

+0

'Otros datos' incluye el montón de GC junto con otros datos :) No estoy seguro de qué más hay allí, pero es seguro suponer que son los datos de tiempo de ejecución requeridos por el CLR. –

Respuesta

1

Descargue MemProfiler de Scitech. Tiene una versión de prueba de 14 días.

El problema que informa a menudo se debe a vistas/recursos que no se pueden eliminar debido a tener una raíz en el montón. Una causa común no es manejar controladores de eventos.

+0

Gracias Mitch. Simplemente jugué un poco con MemProfiler y encontré MUCHO byte [] de "MergedDictionaries" (algo de WPF). Tratando de arreglar eso ahora. Esto no es todo sino algo, ¡gracias! – andyhammar

3

El hecho de que la aplicación use mucha memoria no significa necesariamente que tenga una pérdida de memoria. De la información en su pregunta es difícil afirmar lo que puede estar mal.

Al solucionar problemas de pérdidas de memoria gestionados con WinDbg hago lo siguiente:

  • obtener una visión general del uso del montón con !eeheap (esto reporta el uso del montón y no la pila como usted menciona - cada pila tiene una tamaño predeterminado de 1 MB, a menos que haya cambiado esto, no hay forma de que pueda usar 100 MB en la pila)

  • Haga un !dumpheap -stat para averiguar qué hay en el montón. Lo más probable es que si tiene una pérdida de memoria, el tipo culpable estará entre los mejores consumidores.Para tener una idea de cómo se desarrolla el uso del montón, puede reanudar su aplicación, romperla un poco más tarde y luego repetir el comando !dumpheap -stat.

  • Si encuentra algún tipo con más instancias de las que tendría, salvo, enumere las que utilizan !dumpheap -mt <MT of type>. Esto listará todas las instancias del tipo particular. Elija instancias aleatorias y compruebe las raíces con el comando !gcroot. Esto le dirá qué mantiene activas las instancias en cuestión. Si no hay raíz, estas instancias se recopilarán en algún momento.

UPDATE para responder a sus comentarios:

El montón administrado es sólo una parte de la huella de la memoria de una aplicación administrada. Recuerde que una aplicación .NET es realmente una aplicación dentro de otra aplicación: el proceso de host, que carga el CLR, que a su vez carga su aplicación. Entonces, antes de que su aplicación comience a usar cualquier memoria, la CLR ya ha tenido una participación equitativa. Además de eso, las aplicaciones .NET almacenan el código MSIL y el código compilado JIT como parte de la huella. El CLR también ocupa espacio para varias cosas de contabilidad (por ejemplo, el CLR crea dos AddDomains adicionales para uso interno).

Los números que me das no me parecen excesivos, pero como no conozco tu aplicación, es difícil decir si son excesivos.

100 MB en el montón administrado podría estar bien, dependiendo de lo que esté haciendo su aplicación. ¿Revisaste el montón? Y si es así, ¿qué encontraste?

+0

Gracias Brian! Con un volumen de 139 596 684, mis usuarios de mem más grandes son: 1) System.Byte [] (14949 ítems, mem: 32 217 996), 2) System.String (475 010 ítems, mem: 31 016 248) y 3) System.Windows.Markup.BamlDefAttributeKeyStringRecord (elementos: 230 845 mem: 11 080 560). Los bytes [] s provienen de la lectura de imágenes desde el disco y la creación de BitmapSources. Las cadenas no sé, probablemente una cosa de WPF ... – andyhammar

+0

Otra muestra: compromiso total: 178 Mb, bytes privados: 538 Mb. Profundizando más ... – andyhammar

1

Puede intentar leer this article in the latest MSDN magazine. Se detalla cómo usar VADump para comprender más acerca de dónde se dedica la memoria de un proceso.

Puede descargar VADUMP aquí: http://go.microsoft.com/fwlink/?LinkId=149683

para romper el montón administrado, puede probar con un perfilador de memoria. Personalmente me gusta JetBrains dotTrace.

+0

Gracias Drew, vadump no funcionó para mí ayer, pero lo intenté ahora: informa números que no coinciden con eeheap. He publicado un comentario a mi pregunta. – andyhammar

4

Tuve un problema similar en una aplicación WPF y used UMDH to track donde se asignaba la memoria nativa. (Tenga en cuenta que generalmente es útil set _NT_SYMBOL_PATH para obtener buenos seguimientos de pila de los componentes del sistema operativo.

Los registros mostraron que casi toda la memoria se asignaba en el controlador de video. Encontré que el controlador era más de un año . desfasados; he instalado la última versión desde la web del fabricante y que solucionó el problema

0

una respuesta: Se va a demasiadas ResourceDictionaries fusionadas (una cosa WPF)

Detalles: para ser capaz de ver el diseño en tiempo de diseño en Blend y VS, usamos para fusionar nuestro diccionario de recursos de tema en la mayoría de las páginas xaml. Esto causó una copia de todos los recursos para ser cargado para cada control, se puede leer más información aquí: [Discípulos de WPF] [1]

Así que el único lugar donde los fusiono ahora es App.xaml.CS:

<Application.Resources> 
    <ResourceDictionary> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary 
     Source="pack://application:,,,/Company.Themes;Component/AppTheme.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

Resultados: (correr la aplicación a través de algunas páginas con una prueba de interfaz gráfica de usuario automática)

Antes:

  • Después de carga de la aplicación: 63 Mb
  • Después de uso de las aplicaciones : 177 Mb

Después:

  • Después de carga de la aplicación: 53 Mb
  • Después de uso de las aplicaciones: 97 Mb

Voy a publicar más respuestas como las encuentro! (pensé que sería más fácil para que los lectores puedan ver mi hallazgo como respuestas separadas en lugar de a replys comentarios - bueno?)

[1]: Ref: http://groups.google.com/group/wpf-disciples/web/wpf-and-xaml-coding-guidelines?pli=1

Cuestiones relacionadas