Есть ли утечка памяти в моем WPF Navigation? - PullRequest
6 голосов
/ 18 декабря 2009

Я просматриваю приложение WPF в поисках утечки памяти (используя ANTS Memory Profiler 5.1) и постоянно вижу, как некоторые страницы и элементы управления занимают память, когда их не должно быть.

Итак, я перехожу к Графику сохранения объектов и вижу, что их удерживает, и продолжаю видеть это для каждой страницы:

График удержания объекта http://img683.imageshack.us/img683/3013/ants.jpg

Дело в том, что KeepAlive установлен на false на каждой странице, и я не думаю, что такое свойство существует в пользовательских элементах управления.

Может кто-нибудь сказать мне, что я должен искать? Это даже утечка памяти или это нормальное поведение для приложения WPF?

Ответы [ 2 ]

8 голосов
/ 18 декабря 2009

Да, согласно тому, что вы указали, у вас есть утечка памяти. Когда вы нашли цепочку ссылок, а ее нет в вашем коде, проще всего было бы ... Отражатель.

Изображение говорит: JournalEntryKeepAlive._keepAliveRoot поле содержит ссылку на объект. Пойдемте в Reflector и посмотрим, как этот парень подсел на наш объект.

На этот раз это было легко, и все следы приводят к функции NavigationService.MakeJournalEntry(), а затем к NavigationService.IsContentKeepAlive(). Вот оно:

internal bool IsContentKeepAlive()
{
    bool keepAlive = true;
    DependencyObject dependencyObject = this._bp as DependencyObject;
    if (dependencyObject != null)
    {
        keepAlive = JournalEntry.GetKeepAlive(dependencyObject);
        if (!keepAlive)
        {
            PageFunctionBase base2 = dependencyObject as PageFunctionBase;
            bool flag2 = !this.CanReloadFromUri;
            if ((base2 == null) && flag2)
            {
                keepAlive = true;
            }
        }
    }
    return keepAlive;
}

Теперь вы знаете правила. Объект сохраняется в памяти, если:

  • Это не объект зависимости;
  • Прилагается свойство JournalEntry.KeepAlive имеет значение true;
  • Это не функция PageFunction, и ее нельзя перезагрузить из Uri.

После этого исследования, возможно, стоит прочитать больше о свойстве JournalEntry.KeepAlive в MSDN.

Эта стратегия помогла мне найти много связанных с памятью насекомых. Надеюсь, это вам тоже поможет:).

PS: Если у вас возникнут проблемы с обнаружением этой конкретной утечки, вы можете вставить минимальный образец кода, чтобы мы могли воспроизвести его и дать вам более правильный ответ.

Ура, Anvaka

5 голосов
/ 07 ноября 2012

У меня была та же проблема и та же диаграмма с анализатором памяти Ants. Приложение использовало NavigationWindow для размещения некоторых страниц WPF, и навигация была сделана с помощью следующего кода:

NavigationService.Navigate( new Page1());

Проблема возникла из-за того, что журнал сохранил несколько страниц, которые не могли быть удалены.

Что я сделал, так это заменил NavigationWindow обычным окном, Pages with UserControls и менял пользовательские элементы управления внутри окна, как будто это страницы. Есть много примеров того, как это сделать в Google. После удаления всех вызовов NavigationService.Navigate я мог бы наконец собрать мусор на всех закрытых страницах с помощью профилировщика памяти Ants.

...