Как определить причину бокса в .Net? - PullRequest
8 голосов
/ 06 августа 2009

Резюме

Мы должны понять, какая часть нашего (или третьей стороны, возможно, самого CLR) кода приводит к упаковке целых чисел.

Описание проблемы

У нас довольно большое приложение, где мы наблюдаем высокую скорость выделения System.Int32 экземпляров. С помощью Memory Profiler мы видим небольшое количество длинных существующих Int32 экземпляров (точнее, 18) и 20-25 тысяч Int32 выделений в секунду. Все эти объекты GC собраны как объекты Gen0, система не имеет утечек памяти и может работать в течение длительного времени. При создании моментального снимка памяти GC выполняется до моментального снимка, поэтому моментальный снимок не содержит следов этих «временных» объектов.

Весь наш код был специально написан, чтобы по возможности исключить бокс, и «по замыслу» мы должны вообще не видеть боксы. Таким образом, мы подозреваем, что это какой-то неисчерпаемый забытый бокс в нашем коде или бокс, вызванный сторонним компонентом и / или самим типом CLR.

Система скомпилирована с использованием VS2008 и использует .Net 3.5 (измерения проводились как в отладочной, так и в выпускной сборках, с одинаковым поведением).

Вопрос

Как мы можем (используя windbg, VS2008, Memory Profiler, AQTime или любой другой коммерчески доступный продукт) определить, почему происходит бокс?

Ответы [ 6 ]

2 голосов
/ 06 августа 2009

Весьма удивительно, что методы класса DateTime ToLocalTime / ToUniversalTime вызывают бокс.

Наше приложение (сервер приложений) было недавно изменено, чтобы работать «внутри» только в UTC (чтобы справиться с изменениями в дневное время и т. Д.). Наша клиентская кодовая база осталась на 99% по местному времени.

Сервер приложений преобразует (при необходимости) локальное время в UTC перед обработкой, эффективно вызывая накладные расходы при каждой операции, связанной с временем.

Мы рассмотрим повторное выполнение этих операций "на дому", без бокса.

2 голосов
/ 06 августа 2009

Одно из моих любимых приложений - CLR Profiler, оно даст вам то, что вы ищете, отобразит все ваше приложение, показывая разные поколения. Это бесплатная загрузка от Microsoft, и она чрезвычайно мощная и простая в использовании. Я также включил ссылку на то, как его использовать. (CLR Profiler Download) (Как использовать CLR Profiler)

1 голос
/ 06 августа 2009

Вы провели статический анализ вашего кода? Возможно NDepend может помочь вам найти методы и типы, которые упаковывают и распаковывают значения.

Пробная версия NDepend находится в свободном доступе, поэтому стоит попробовать проанализировать сборки, как вашу, так и стороннюю.

0 голосов
/ 06 августа 2009

Операции упаковки и распаковки могут быть обнаружены путем статического анализа вашего кода. Ищите правила fxcop.

Профилировщик может также помочь вам, так как такое большое количество выделений в секунду, несомненно, вызовет большие издержки.

Удачи и держите нас в курсе ваших результатов.

0 голосов
/ 06 августа 2009

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

Если вы выделяете достаточное количество времени для запуска большой активности GC, тогда у вас есть хорошие шансы взломать код, в котором происходит распределение по боксу.

Преимущество этого в том, что вам не нужны новые инструменты (при условии, что у вас есть достойная IDE или отладчик)

0 голосов
/ 06 августа 2009

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

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