Утечка памяти в .NETCF - создание динамических элементов управления? - PullRequest
1 голос
/ 14 октября 2008

У меня проблема с утечкой памяти в приложении .NET CF.

Использование об / мин Я определил, что динамически создаваемые элементы управления не собираются мусором, как ожидалось. Выполнение одного и того же фрагмента кода в .NET Window Forms ведет себя по-разному и располагает элементом управления, как я ожидал.

См. Выходные данные об / мин через PerfMon для счетчика Process Heap :
alt text

GC Heap:
alt text

Мое лучшее предположение состоит в том, что Слабая ссылка на Панель по неизвестной причине не делает объект пригодным для GC, не так ли?

Обратите внимание: Несмотря на то, что Dispose () решает проблему для образца, я не могу легко включить его в существующее приложение, так как это не так ясно, чтобы определить когда объект больше не используется.

Я включил упрощенную версию исходного кода для иллюстрации проблемы:

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 
        }
    }
}

Обновление:
1. Вызов GC.Collect () также не приводит к очистке панелей.
2. Использование .NET CF 2.0 SP1 на устройстве Windows CE 4.2.

Ответы [ 4 ]

3 голосов
/ 15 октября 2008

Некоторая дополнительная информация, объясняющая это поведение.

По мнению Ильи Туманова :

Все, что связано с интерфейсом NETCF, намеренно удален из области видимости оно никогда не собирается . Это поведение отличается от рабочего стола и был изменено в NETCF V3.5 (если не работает в режиме совместимости).

Это так отличается, потому что управляемый интерфейс занятия на NETCF полностью отличается от рабочего стола. Они худые обертки над нативной реализацией что было необходимо для достижения приемлемого производительность.

Я не уверен, что такой ресурс есть. Но на самом деле все, что вам нужно знать, это: это никогда не собирается, должен позвонить распоряжаться. Вы на самом деле должны это сделать на рабочем столе, но если вы не его путь более прощающий. Не скоро NetCF.

2 голосов
/ 15 октября 2008

Форма не автоматически удаляет все элементы управления, созданные в ее коде, поскольку она не может знать, что она существует. Чтобы автоматически преобразовать форму «Форма в форму» при ее удалении, необходимо добавить ее в коллекцию элементов управления.

Теперь в вашем случае это может ничего не делать. Я не могу сказать, надуман ли твой пример или реальный мир. Если это реальный мир, то поведение ожидается, поскольку Panel не собирается, когда переменная выходит из области видимости (не уверен, что это происходит и на рабочем столе). Он становится доступным для сбора, но это просто означает, что на следующем проходе сбора он будет удален. Если вы не вызываете сборщик мусора, он не будет освобожден.

Я бы настоятельно рекомендовал вам посмотреть веб-трансляцию MSDN по управлению памятью в CF . Это дает гораздо более подробное объяснение того, что происходит под капотом - гораздо больше, чем мы могли бы дать в ответе здесь.

1 голос
/ 07 января 2009

Я думаю, вам также нужно динамически удалить Event Click ClickHandler, как вы можете видеть из этого блога http://blogs.msdn.com/stevenpr/archive/2007/03/08/finding-managed-memory-leaks-using-the-net-cf-remote-performance-monitor.aspx

Это тоже от Стивена Пратшнера.

Кстати, упомянутая выше веб-трансляция связана здесь: http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?culture=en-US&EventID=1032318791&CountryCode=US

Надеюсь, это поможет!

1 голос
/ 14 октября 2008

Вы уверены, что у вас утечка памяти? Сборщик мусора .NET Compact Framework работает немного иначе, чем в полной .NET Framework. Из блога Стивена Пратшнера :

Сбор инициируется, когда:

  • Выделено 1 МБ объектов,

  • Приложение перемещено в фоновый режим,

  • Не удалось выделить память

  • Приложение вызывает GC.Collect.

...