Утечка памяти в .NETCF – создание динамических элементов управления?

StackOverflow https://stackoverflow.com/questions/200786

Вопрос

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

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

См. вывод RPM через PerfMon для Куча процесса прилавок:
alt text

Куча GC:
alt text

Я предполагаю, что слабая ссылка на панель по какой-то неизвестной причине не делает объект подходящим для GC, не так ли?

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

Я включил упрощенную версию источника, чтобы проиллюстрировать проблему:

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.

Это было полезно?

Решение

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

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

Все, что пользовательский интерфейс, связанный с NetCF, преднамеренно удаляется из прицела GC, поэтому он никогда не собирается.Такое поведение отличается от настольного компьютера и было изменено в NetCF v3.5 (если не работает в режиме совместимости).

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

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

Другие советы

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

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

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

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

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

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

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

  • Возникает сбой при выделении памяти

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

Я думаю, вам также нужно динамически удалить EventHandler Button Click, как вы можете видеть из этого блога: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?cultural=en-US&EventID=1032318791&CountryCode=US

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top