Как определить, где экземпляры объекта все еще ссылаются? - PullRequest
10 голосов
/ 28 апреля 2011

После запуска профилировщика VS2010 с отслеживанием продолжительности жизни объекта в моем приложении это происходит в определенном классе:

Количество экземпляров ---------- 1 418 276
% Всего экземпляров ---------------------% 5.8
Всего выделено байт -------158 846 912
% Всего байт --------------------------% 5.94
Gen 0 Собранных экземпляров --------- 5 196
собранных экземпляров поколения 1 -------- 54 894
собранных экземпляров поколения 2 ---- 747 874
Экземпляры Alive In End --------- 610 312
Gen 0 Собранных байтов ----------- 581 952
Gen 1 собрано байтов --------- 6 148 128
Gen 2 собрано байтов --------- 3 761 888

Как видите, половина всех созданных экземпляров заканчиваются в основном как Gen 2 , а другая половина остается в живых до конца Приложения .[ ха, ха, ха, ха, остаться в живых, остаться в живых ... -> Хорошо, извините, я не смог устоять ... ]

Чтоменя беспокоит то, что эти экземпляры должны иметь очень короткое время жизни (это в основном класс поля данных - это может быть структура, но я предпочел сделать это классом, чтобы «активировать» GC на нем).
Эти экземпляры создаются путем чтения очень больших двоичных файлов (каждая строка является классом / записью) и передаются через очередь небольшого размера делегатом / событием работникам, которые в основном просто читают его, помещают его в очереди (которые очень регулярно исключается из очереди), а затем завершается (фоновые рабочие заканчиваются нормально).Я предполагаю, что события не подписываются, когда рабочих больше не существует.

Итак, есть ли способ определить, где эти ссылки скрывают ?Потому что, если они не GC, на них все еще есть ссылки, но как сказать наверняка?Я устал угадывать и пытаться выдвигать так много гипотез, поэтому, если у кого-то есть более рациональные рекомендации или справедливый контрольный список и / или инструменты / точные профилировщики, на которые можно посмотреть, я приветствую это.

Дополнительные ресурсы дляответы
Visual GCRoot через DGML - Спасибо Ричарду Салаю
Кроме того, это видео GCRoot Demo от Криса Ловетта очень познавательно по этому вопросу.

Ответы [ 3 ]

7 голосов
/ 28 апреля 2011
  1. Включить неуправляемую отладку на вкладке «Отладка» свойств вашего проекта
  2. Запустите приложение и установите точку останова в точке, где вы хотите исследовать типы
  3. В Немедленное окно, введите:
.load sos
!DumpHeap -type <partial type name>

Это вернет что-то вроде:

 Address       MT     Size
026407c0 53ecee20       16     

Тогда вы можете взять Address и использовать GCRoot чтобы найти место, где он укоренен:

!GCRoot 026407c0

Крис Ловетт (через Тесс Феррандез ) создал очень аккуратную утилиту, которая преобразует низкоуровневую GCRootвывод в DGML-график, который может упростить диагностику.

В качестве альтернативы Мохамед Махмуд создал расширение отладчика , которое позволяет генерировать график из WinDBG, но он не работает в VisualStudio, так что вы можете придерживаться утилиты Криса, чтобы избежать установки средств отладки.

Сказав это, текстового вывода вполне может быть достаточно для отслеживания событий.Если вы хотите получить информацию о выходе GCRoot, введите !help GCRoot в ближайшем окне.

2 голосов
/ 28 апреля 2011

РЕДАКТИРОВАТЬ 2018: если у вас есть Visual Studio 2015+, тогда весь процесс будет намного проще: Учебник по MSDN .

Если вы хотите точно знать, какие экземпляры живы, все, что вам нужно сделать, - это создать дамп процесса с Adplus, который поставляется с инструментами отладки для Windows . (теперь это часть загрузки SDK.)

затем в WinDBG используйте тип! Dumpheap Команда, чтобы увидеть, какие классы, какие классы еще до.

тогда вы можете использовать! Gcroot, чтобы увидеть, кто содержит эту ссылку.

0 голосов
/ 31 августа 2018

Вы можете набрать команду gcroot.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...