Вопрос

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

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

Это было полезно?

Решение

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

Вы можете сделать это, написав Profiler CLR, который работает внутри процесса, который вы нацеливаетесь. Profillers 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.

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

Другие советы

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

Исходный API профилирования называется IcorProfilerCallback. Позже версии называются COREPROFILERCALLBACK2 и COREPROFILERCALLBACK3. Если вы гугтете те имена, вы найдете именно ответы, которые вы ищете. На CodeProject вы можете увидеть практический пример: Создание пользовательского профилировщика .NET

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top