Что на самом деле делает кнопка Visual Studio Performance Profiler Force GC?

Я пытаюсь отследить утечки памяти в своем приложении с помощью Visual Studio Performance Profiler

Я использую профилировщик, чтобы:

  1. выполнять действия
  2. Снимок
  3. Force GC
  4. снимок снова

И я вижу, что весь мой объектный мусор правильно собран.

введите здесь описание изображения

Я делаю то же самое, но использую свое приложение:

  1. выполнять действия
  2. Снимок
  3. Принудительно использовать сборщик мусора во время выполнения с помощью кода:

    GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();

  4. снимок снова

Но на этот раз объекты не собираются и все еще находятся в памяти.

Так в чем разница между кнопкой Force GC и кодом GC.Collect(), который я вызываю?


person user1    schedule 29.01.2020    source источник
comment
Вы не можете заставить коллекционера что-либо делать, это совершенно не детерминировано. Сказав это, это просто случайность, когда использование профилировщика покажет вам что-то другое.   -  person HimBromBeere    schedule 29.01.2020
comment
Если вы принудительно соберете коллекцию и ваша утечка исчезнет, ​​это никогда не было утечкой. Почему вы пришли к выводу, что у вас утечка? Кроме того, если вы выделяете объекты тем же методом, что и оператор GC.Collect();, если вы профилируете сборку DEBUG или если приложение профилировщика ведет себя как отладчик, оно продлит время жизни локальных переменных, возможно, достаточно, чтобы сделать они будут живы за пределами коллекции.   -  person Lasse V. Karlsen    schedule 29.01.2020
comment
@ LasseV.Karlsen В данный момент я просто ищу утечки информации о переходах между страницами и страницами. Я думаю, что вы, возможно, правы - страница может закрывать сама себя и вызывать GC.Collect, но поскольку это закрывается сама страница, она может удерживать все во время GC.Collect   -  person user1    schedule 29.01.2020
comment
Если вы разместили код коллекции внутри страницы, независимо от того, что находится в вашем приложении, страница может удерживать ресурсы, да. Одно распространенное заблуждение, которое я вижу, когда все время говорю о приложениях .NET, заключается в том, что люди склонны полагать, что они используют много памяти. Однако это просто сборщик мусора, работающий по назначению. Нет смысла сводить память к минимуму, если у вас ее много. Если, однако, он никогда не вернется к некоторому базовому уровню или базовый уровень неуклонно растет, тогда вам нужно искать утечки.   -  person Lasse V. Karlsen    schedule 29.01.2020


Ответы (1)


Итак, спасибо @Lass V. Karlsen за то, что он указал мне в правильном направлении этим комментарием: Что на самом деле делает кнопка Force GC в Visual Studio Performance Profiler?

Если подумать, это было совершенно очевидно.

Мой Page избавлялся от самого себя и в методе Dispose, который я вызывал:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

и, конечно же, поскольку на тот момент страница была еще жива, она не собиралась сборщиком мусора.

Вместо этого я решил сделать следующее:

#if DEBUG
     Task.Run(async () =>
     {
         await Task.Delay(500);                   
         GC.Collect();
         GC.WaitForPendingFinalizers();
         GC.Collect();
     });
#endif

Обратите внимание, что я обернул его директивой компилятора DEBUG, поскольку я не думаю, что это рекомендуемый способ сделать это, но с целью поиска утечек памяти он работает хорошо

person user1    schedule 29.01.2020