Как проверить, правильно ли расположен мой объект?

Интересно, есть ли «уловка», которая позволяет узнать, были ли используемые объекты в части кода правильно (полностью) удалены или, другими словами, не создают утечек памяти.

Допустим, у меня есть контейнер объектов GDI (или другой, который мне нужно явно удалить)

public class SuperPen 
{
    Pen _flatPen, _2DPen, _3DPen;
    public SuperPen() 
    {
        _flatPen = (Pen)Pens.Black.Clone();
        _2DPen = (Pen)Pens.Black.Clone();
        _3DPen = (Pen)Pens.Black.Clone();
    }
}

Теперь, когда мне нужно удалить объекты GDI, я делаю:

public class SuperPen : IDisposable
{
    Pen _flatPen, _2DPen, _3DPen;
    public SuperPen()
    {
        _flatPen = (Pen)Pens.Black.Clone();
        _2DPen = (Pen)Pens.Black.Clone();
        _3DPen = (Pen)Pens.Black.Clone();
    }

    public void Dispose()
    {
        if (_flatPen != null) { _flatPen.Dispose(); _flatPen = null; }
        // HERE a copy paste 'forget', should be _2DPen instead
        if (_flatPen != null) { _flatPen.Dispose(); _flatPen = null; }
        if (_3DPen != null) { _3DPen.Dispose(); _3DPen = null; }
    }
}

Подобная ситуация может произойти, если вы добавите новый «одноразовый» объект и забудете его удалить и т. Д. Как я могу обнаружить свою ошибку, я имею в виду, проверить, правильно ли был удален мой SuperPen?


person serhio    schedule 02.02.2010    source источник
comment
Мой спонтанный вопрос: почему вы клонируете Pens.Black? Но, может быть, оно используется только для иллюстрации вопроса?   -  person Fredrik Mörk    schedule 02.02.2010
comment
@Frederik: Just - это способ инициализировать пустое перо. Я мог бы также сделать = new Pen(Color.Black); - сделайте это, потому что покажите, что мой объект был создан и, наконец, ему понадобится свободное удаление/память.   -  person serhio    schedule 02.02.2010


Ответы (4)


Не думайте, что это возможно; лучшее, что вы можете сделать, это получить профилировщик (например, профилировщик муравьев) и измерить Это. Если вы обнаружите, что у вас чрезмерная утечка памяти (через профилировщик), значит, что-то не так.

Кроме использования профилировщика, я не уверен в каких-либо автоматических методах, которые помогут вам идентифицировать нераспределенные ресурсы.

person Graviton    schedule 02.02.2010
comment
Если это невозможно, то как ANTS это делает? - person Dan Tao; 02.02.2010
comment
@Dan: я предполагаю, что через API профилирования: blong.com/Conferences/ DCon2003/Internals/Profiling.htm - person Sam Harwell; 02.02.2010
comment
@ 280Z28: Я имел в виду это как риторический вопрос - я почти уверен, что тот факт, что ANTS делает это (через .NET API, не иначе), означает, что это возможно. Тем не менее, я, конечно, не стал бы делать это сам, когда что-то вроде ANTS уже существует. - person Dan Tao; 02.02.2010

Такой инструмент, как MemProfiler или Профилировщик памяти ANTS выявит утечки памяти (у обоих есть пробные версии).

person Mitch Wheat    schedule 02.02.2010

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

person C. Ross    schedule 02.02.2010
comment
Это особенно относится к выпускным сборкам: вам не следует переопределять финализатор для любого объекта, который не напрямую содержит неуправляемые ресурсы из-за ненужного и значительные потери производительности. Неуправляемые ресурсы почти всегда должны храниться в классе, производном от SafeHandle (или аналогичном), чтобы также снизить нагрузку на сборщик мусора. - person Sam Harwell; 02.02.2010

Я полагаю, что FxCop (доступный отдельно или интегрированный в версии Team System VS2005+) обнаружит это.

person Joe    schedule 02.02.2010