Могу ли я получить экземпляры живых объектов определенного типа в C #? - PullRequest
3 голосов
/ 14 июля 2009

Это вопрос C # 3.0. Могу ли я использовать классы отражения или управления памятью, предоставляемые .net Framework, для подсчета общего числа живых экземпляров определенного типа в памяти?

Я могу сделать то же самое, используя профилировщик памяти, но это требует дополнительного времени для сброса памяти и требует стороннего программного обеспечения. Мне нужен только мониторинг определенного типа, и я хочу легкий метод, который может легко перейти к юнит-тестам. Цель подсчета живых экземпляров - убедиться, что у меня нет ожидаемых живых экземпляров, которые вызывают «утечку памяти».

Спасибо.

Ответы [ 2 ]

1 голос
/ 14 июля 2009

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

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

Если вы хотите рассмотреть счетчик экземпляров, он должен выглядеть примерно так:

public class MyClass : IDisposable
    public MyClass()
    {
        ++ClassInstances;
    }

    public void Dispose()
    {
        --ClassInstances;
    }

    private static new object _ClassInstancesLock;
    private static int _ClassInstances;
    private static int ClassInstances
    {
        get
        {
            lock (_ClassInstancesLock)
            {
                return _ClassInstances
            }
        }
    }

Это просто очень грубый образец, тесты на компиляцию отсутствуют; 0% гарантия безопасности потока (критично для такого подхода), и она оставляет дверь широко открытой для вызова Dispose, экземпляра в противоположность декременту, но для объекта не для правильного GC. Чтобы диагностировать этот набор радости, вам понадобится, как вы уже догадались, профессиональный профилировщик - или хотя бы windbg.

Редактировать: Я только что заметил самую последнюю строку вашего вопроса и хотел сказать, что мой вышеупомянутый подход, столь же дрянной и склонный к сбоям, почти гарантированно обманет вас и обманет вас о истинное количество случаев, если вы испытываете утечку. Лучший инструмент IMO для решения этих проблем - ANTS Memory Profiler. Версия 5 представляет собой двойное преимущество в том смысле, что они разбили профилировщик производительности и памяти на два отдельных SKU (раньше их объединяли), но Memory Profiler 5.0 работает очень быстро. Профилирование этих проблем, как молаз, было медленным, но они обошли его где-то дома.

Если это не для личного проекта с 0 намерениями перераспределения, вы должны инвестировать несколько сотен долларов, необходимых для ANTS - но во что бы то ни стало, сначала используйте его пробный период. Это отличный инструмент для точно такого рода анализа.

0 голосов
/ 14 июля 2009

Единственный способ, которым я вижу это, - без какой-либо инструментария использовать CLR Profiling API для отслеживания времени жизни объекта. Я не знаю ни одного API, доступного для управляемого кода, чтобы делать то же самое, и, насколько я знаю, CLR нигде не хранит список живых объектов (поэтому даже с API-интерфейсом профилировщика вы должны создавать данные структуры для этого сами).

В VB.NET есть функция, позволяющая отслеживать объекты в отладчике, но на самом деле он генерирует дополнительный код специально для этого (который в основном регистрирует все созданные объекты во внутреннем списке слабых ссылок). Вы также можете сделать это, например, используя PostSharp для постобработки ваших сборок.

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