Pregunta

Tengo un problema con una pérdida de memoria en una aplicación .NET CF.

Usando RPM lo identifiqué creando dinámicamente Los controles no son basura recolectada como se esperaba. Ejecutar el mismo fragmento de código en .NET Window Forms se comporta de manera diferente y elimina el control como esperaba.

Vea la salida de RPM a través de PerfMon para el contador Process Heap :
alt text

Montón GC:
alt text

Mi mejor conjetura es que la Referencia débil al panel es, por alguna razón desconocida, no hacer que el objeto sea elegible para GC, ¿puede ser?

Tenga en cuenta: Aunque Dispose () resuelve el problema para la muestra, no puedo incorporarlo fácilmente a la aplicación existente ya que no es tan claro para determinar cuándo el objeto ya no está en uso.

He incluido una versión simplificada de la fuente para ilustrar el problema:

using System;
using System.Windows.Forms;

namespace CFMemTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // Calling this event handler multiple times causes the memory leak
        private void Button1_Click(object sender, EventArgs e)
        {
            Panel uc = new Panel();
            // Calling uc.Dispose() cleans up the object 
        }
    }
}

Actualización:
1. Llamar a GC.Collect () tampoco hace que se limpien los paneles.
2. Usar .NET CF 2.0 SP1 en un dispositivo con Windows CE 4.2.

¿Fue útil?

Solución

Aquí hay información adicional que explica este comportamiento.

Según Ilya Tumanov :

  

Todo lo relacionado con la IU en NETCF es   intencionalmente eliminado del alcance GC por lo   nunca se recoge . Este comportamiento   es diferente del escritorio y ha sido   cambiado en NETCF V3.5 (a menos que se esté ejecutando   en modo de compatibilidad).

     

Es muy diferente porque la interfaz de usuario administrada   Las clases en NETCF son completamente   diferente del escritorio Son delgadas   envoltorios sobre implementación nativa   que era necesario para lograr aceptable   rendimiento.

     

No estoy seguro de que haya tal recurso.   Pero en realidad, todo lo que necesitas saber es:   nunca se recoge, hay que llamar   disponer. En realidad deberias hacer eso   en el escritorio también, pero si no lo hace   es mucho más indulgente. No pronto   NETCF.

Otros consejos

Un formulario no desecha automáticamente todos los controles creados en su código, ya que no tiene forma de saber que existe. Para hacer que el Formulario se forme para desecharlo automáticamente cuando está Desechado, debe agregarlo a la colección de Controles.

Ahora en tu caso eso no puede hacer nada. No puedo decir si tu ejemplo es artificial, o del mundo real. Si es en el mundo real, entonces se espera el comportamiento, ya que el Panel no se recopila cuando la variable queda fuera del alcance (tampoco estoy seguro de que lo haga en el escritorio). Está disponible para la recolección, pero eso simplemente significa que en la próxima pasada de recolección será barrido. A menos que esté causando un GC, no se liberará.

Le recomiendo que eche un vistazo a MSDN webcast sobre gestión de memoria en el CF . Proporciona una explicación mucho más completa sobre lo que está sucediendo bajo el capó, mucho más de lo que podríamos proporcionar en una respuesta aquí.

¿Estás seguro de que tienes una pérdida de memoria? El recolector de basura de .NET Compact Framework funciona de manera ligeramente diferente a la de .NET framework completo. Del blog de Steven Pratschner :

  

Se inicia una recopilación cuando:

     
      Se han asignado
  • 1 MB de objetos,

  •   
  • Una aplicación se mueve al fondo,

  •   
  • Se produce un error al asignar memoria

  •   
  • Una aplicación llama a GC.Collect.

  •   

Creo que también necesitas eliminar dinámicamente el botón Click EventHandler, como puedes ver en este blog: http://blogs.msdn.com/stevenpr/archive/2007/03/08/finding-managed-memory-leaks-using-the-net-cf-remote-performance-monitor.aspx

También es de Steven Pratschner.

Por cierto, el webcast mencionado anteriormente está vinculado aquí: http://msevents.microsoft.com/cui/ WebCastEventDetails.aspx? Culture = en-US & amp; EventID = 1032318791 & amp; CountryCode = US

¡Espero que esto ayude!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top