(Полное раскрытие: я в команде 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, и его блог содержит массу отличной информации о профилировании в целом, включая все сумасшедшие ловушки и проблемы, с которыми вы можете столкнуться.