2012-04-16 5 views
11

Tengo un comportamiento extraño aquí: Obtengo una pérdida masiva de memoria en producción al ejecutar una aplicación WPF que se ejecuta en un DLOG-Terminal (Windows Embedded Standard SP1) que se comporta perfectamente bien si Lo ejecuto localmente en un escritorio normal (Win7 prof.)Las WeakReferences no se liberan en el SO integrado

Después de muchos intentos fallidos de encontrar algún problema, puse uno directamente al lado de mi monitor, instalé ANTs MemoryProfiler e hice una prueba de una hora para simular las operaciones del usuario en ambos la terminal y mi PC de desarrollo.

El resultado es que, debido a algunas razones extrañas, el sistema integrado acumula una gran cantidad de objetos WeakReference y EffectiveValueEntry [].

Aquí están algunas fotos son:

Desarrollo (PC): enter image description here

enter image description here

y el terminal: enter image description here

basta con ver la lista de clase ... enter image description here

¿Alguien ha visto algo así antes y hay soluciones conocidas para esto? ¿Dónde puedo obtener ayuda?

(PS los terminales donde instalan con imágenes preparadas para .net4)

PPS: para el primer votante: Creo que la pregunta es clara: ¿cómo puedo solucionar este problema. Se podría argumentar si esto es un problema de TI/OS frente a un problema de programación pero creo que si he puesto esto en servidor de fallos se conseguirá un cierre fuera de tema en ningún momento ...

ACTUALIZACIÓN: Pude encontrar una gran parte del problema, pero se siente un poco como C++: Utilizo una clase de elementos tipo ViewModel para una lista WPF que proporciona (entre otros) un ICommand (RelayCommand-pattern). Los elementos se crearon sobre la marcha en el getter de un ViewModel-Property para la vista y parece que la aplicación/GC nunca liberó esos comandos no utilizados, o las suscripciones a CanExecuteChanged, el perfilador de memoria los muestra como "sostenidos por un referencia débil ". Cambié mi código para reutilizar los elementos-viewmodels y Dispose/set para anular todas las propiedades usadas en su Dispose y usar esto también como clean -como dije: se siente como "delete" en esos viejos días de C++. Además de esto, uso un GC forzado. Recoja cada 30 minutos (si, lo sé, nunca debería hacerlo, pero no tengo otra solución hasta ahora). Con esta configuración, las aplicaciones se ejecutan durante más de 6 horas sin problemas hasta el momento, pero no se siente bien.

No puedo entender por qué esas WeakReferences no son reclamados, ya que son en mi máquina de escritorio ...

Alguna idea sobre esto? ¡Por favor!

ACTUALIZACIÓN: yo todavía no soy capaz de precisar este problema, pero veo un comportamiento extraño: Si utilizo PC en cualquier lugar para observar la operación de mi software en uno de los terminales el problema desaparece! Incluso después de ejecutar 8hr.el software corre como debería, incluso liberará la memoria (pongo una pequeña pantalla de visualización en la pantalla principal, digamos que me conecto a la terminal y veo que la memoria está baja) después de esperar unos minutos la memoria se recupera)

Así que creo que Devin (una respuesta más abajo) tiene una ventaja en la dirección correcta: algo en el software Remote-Control desbloquea el hilo finalizador o lo que esté bloqueando el GC, ya sea el teclado/mouse simulado o lo que sea .

¿Alguna idea de esto?

+1

Este es un problema conocido al ejecutar la compilación Debug de ensamblados de VB.NET sin un depurador adjunto. Se filtran las referencias débiles que se generan automáticamente para realizar un seguimiento de los eventos WithEvents para la compatibilidad con Edit + Continue. Aparte de eso, es imposible modificar el código de ingeniería de las capturas de pantalla. –

+1

Primero: este código no es ni VB.NET (no debería importar) ni está compilado con el conjunto DEPURACIÓN - además de esto, ambos se ejecutaron sin tener un depurador conectado, comenzaron desde la misma versión del mismo generador de perfiles, utilizaron el mismos ensamblajes y archivos (Xcopied) al mismo tiempo con casi los mismos datos, y ¿qué crees que podrías obtener al ver toneladas de líneas de código WPF (o quieres ** todo ** el código? eso es un poco de MB archivos de texto ... no de código abierto por cierto) – Carsten

+0

Referencia para el problema @HansPassant mencionado (sí, VB.NET sería importante aquí): http://support.microsoft.com/?kbid=919481 – roken

Respuesta

5

Tuvimos un problema (un tanto) similar al ejecutar mi aplicación en una tableta. La memoria se recuperaría cuando se ejecutara en un escritorio, pero no cuando se ejecutara en una tableta u otro dispositivo que utilizara un panel de entrada de PC. El problema es que la cola de finalización se estaba atascando. El finalizador de objetos COM estaba esperando ejecutar algo en el hilo principal, que no tenía un bucle de mensaje.

La solución fue encontrar un tiempo adecuado para invocar Application.DoEvents(). Teníamos un método que se llamaría intermitentemente y lo invocamos con cada décima llamada. No sé si este es el mismo problema que está teniendo, pero tal vez pueda arrojar algo de luz.

EDITAR: Tengo que dejar claro, en general, llamar al DoEvents() es una mala idea. Funciona en ese caso porque no hay ninguna interfaz de usuario en ese hilo ni nada más que pueda suceder con el que esos eventos puedan interferir.

+0

muy interessting - ¡Comprobaré esto de una vez! - BTW: ¿la desactivación/cierre del teclado del software (?) También resolvió el problema? Realmente no necesito el teclado en los dispositivos. – Carsten

+0

Si no recuerdo mal, al deshabilitar el panel de entrada del teclado, resolví el problema, pero ya no tengo el dispositivo, así que no puedo verificarlo. – Devin

+0

Después de comprobar esto por un tiempo, tengo que decir: no, no resuelve el problema.Eliminé el software del panel de entrada e intenté usar WinForms-DoEvent e incluso una invocación manual de WPF-Dispatcher, pero gracias por su sugerencia, creo que apunta en la dirección correcta. – Carsten

2

De las capturas de pantalla es interesante ver que el LOH crece al mismo tiempo que el espacio usado no crece mucho. El espacio libre está creciendo mucho en LOH, lo que indica la fragmentación de la memoria debido a objetos fijados. Esto parece un hilo de finalizador atascado que impide la limpieza de los objetos gestionados. Debería obtener un volcado de memoria y comprobar en qué método estaba enganchada la secuencia del finalizador. Puedes hacer esto bastante fácil con Windbg.

Cuestiones relacionadas