Получение глобальных корней из .NET программ - PullRequest
3 голосов
/ 10 октября 2010

Я недавно начал использовать инструменты профилирования ANTS для производственных работ.Помимо удивления от их удивительности, я не мог не задаться вопросом, как они работают.Например, одна из наиболее полезных функций позволяет вам визуализировать глобальные корни работающей программы с количеством ссылок на значения различных типов.

Как этот инструмент получает эту информацию?

Ответы [ 2 ]

17 голосов
/ 10 октября 2010

(Полное раскрытие: я в команде Visual Studio Profiler, но приведенная ниже информация является общедоступной)

Это можно сделать, написав профилировщик CLR, который выполняется внутри целевого процесса.Профилировщики CLR - это C ++ COM-объекты, которые создаются экземпляром среды выполнения при установке переменных окружения COR_PROFILER и COR_PROFILING_ENABLED (см. здесь ).Существует два основных интерфейса профилирования CLR , в частности ICorProfilerCallback и ICorProfilerInfo.ICorProfilerCallback - это то, что CLR использует для уведомления о конкретных событиях, на которые вы подписаны (загрузка модулей, функция JIT-компиляция, создание потоков, события GC), тогда как ICorProfilerInfo может использоваться вашим профилировщиком для получения дополнительной информации о потоках,модули, типы, методы и метаданные для загруженных сборок.Этот интерфейс - то, что вы могли бы использовать для получения символьной информации о выделенных типах.

С вашим профилировщиком в процессе вы можете принудительно настроить GC через ICorProfilerInfo::ForceGC,После завершения GC ваш профилировщик получит уведомление через ICorProfilerCallback2::GarbageCollectionFinished, а вы получите корневые ссылки через ICorProfilerCallback2::RootReferences2.Когда вы объединяете корневую справочную информацию с ICorProfilerCallback::ObjectReferences, вы можете получить полный граф ссылок на объект для вашего приложения .NET.

Вы можете получить больше информации в реальном времени, используя ICorProfilerCallback::ObjectAllocated обратный вызов для определения момента создания отдельных объектов CLR.Это может быть дорогостоящим, поскольку вы выполняете как минимум дополнительный вызов функции для каждого выделенного объекта.Вы можете отслеживать отдельные объекты, сопоставив присвоенный CLR ObjectID своему внутреннему идентификатору.ObjectID для данного объекта является эфемерным указателем, поскольку он может изменяться по мере сбора мусора, что может привести к перемещению объектов во время сжатия.Этот процесс иллюстрируется здесь .Вы можете использовать информацию из ICorProfilerCallback::MovedReferences для отслеживания движущихся объектов.

Чтобы активировать обратные вызовы, упомянутые выше, вам необходимо сообщить API профилирования CLR, что вы заинтересованы в них,Вы можете сделать это, указав COR_PRF_MONITOR_GC и COR_PRF_MONITOR_OBJECT_ALLOCATED как часть своих флагов событий при вызове ICorProfilingInfo::SetEventMask.

Дэвид Броман - разработчик в профилировщике CLR, и его блог содержит массу отличной информации о профилировании в целом, включая все сумасшедшие ловушки и проблемы, с которыми вы можете столкнуться.

3 голосов
/ 10 октября 2010

Профилировщики, такие как ANTS, используют «API профилирования», представленный самим CLR, который может просто сказать вам, что происходит внутри CLR. Например, существует метод обратного вызова API, который происходит при выделении объекта с метким именем ObjectAllocated () . Аналогично, есть события, когда вводятся методы, когда создаются потоки и т. Д. И т. Д.

Исходный API профилирования называется ICorProfilerCallback. Более поздние версии называются CoreProfilerCallback2 и CoreProfilerCallback3. Если вы гуглите эти имена, вы найдете именно те ответы, которые ищете. На codeproject вы можете увидеть практический пример: Создание настраиваемого .NET Profiler

Последнее замечание: API нельзя использовать из управляемого кода, такого как C # и VB.NET. Он доступен только из неуправляемого кода, например, C или C ++. Поэтому приложение C # не может использовать этот API, например, для проверки своего поведения и объектов.

...