Установка объектов в Null/Nothing после использования в .NET

Должны ли вы установить все объекты в null (Nothing в VB.NET) после того, как вы закончили работу с ними?

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

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

Так что, учитывая все это, ускорит ли установка значения null освобождение памяти системой, поскольку ей не придется разбираться с тем, что объект больше не находится в области видимости, и есть ли у этого какие-либо плохие побочные эффекты?

Статьи MSDN никогда не делают этого в примерах, и в настоящее время я делаю это, поскольку не вижу вреда. не вижу вреда. Однако я столкнулся с разными мнениями, поэтому любые комментарии будут полезны.

Комментарии к вопросу (1)
Решение

Карл абсолютно правилен, нет никакой потребности установить объекты аннулировать после использования. Если объект осуществляет 'IDisposable', просто удостоверьтесь, что Вы называете 'IDisposable. Расположите ()' когда you' ре, сделанное с тем объектом (обернутый в 'попытку'.. 'наконец', или, 'использование ()' блок). Но даже если Вы don' t не забывают звонить, 'Располагают ()', finaliser метод на объекте должен звонить, 'Располагают ()' для Вас.

Я думал, что это было хорошим лечением:

и это

Там isn' t любой пункт в попытке к второму предположению GC и его стратегии управления, потому что it' s самонастраиваемый и непрозрачный. Была хорошая дискуссия о внутренних работах с Джеффри Рихтером на Дот-Нет-Рокс здесь: [Джеффри Рихтер на Windows Memory Model] [3] и У книги Richters CLR через C# глава 20 есть большое лечение:

[3]: http://www.dotnetrocks.com/default.aspx? showNum=361

Комментарии (8)

Другая причина постараться не устанавливать объекты аннулировать, когда Вы сделаны с ними, состоит в том, что это может на самом деле поддержать их для дольше.

например.

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is now eligible for garbage collection         

    // ... rest of method not using 'someType' ...
}

позволит объекту, отнесенному someType быть GC' d после требования к " DoSomething" но

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is NOT eligible for garbage collection yet
    // because that variable is used at the end of the method         

    // ... rest of method not using 'someType' ...
    someType = null;
}

май иногда поддерживает объект до конца метода. МОНЕТА В ПЯТЬ ЦЕНТОВ обычно будет оптимизируемый далеко назначение на пустой указатель, таким образом, обе части кодекса закончат тем, что были тем же.

Комментарии (2)

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

Комментарии (2)

В целом, there' s никакая потребность аннулировать объекты после использования, но в некоторых случаях я нахожу it' s хорошая практика.

Если объект осуществляет IDisposable и хранится в области, я думаю it' s хороший, чтобы аннулировать его, только избегать использования склонного объекта. Ошибки следующего вида могут быть болезненными:

this.myField.Dispose();
// ... at some later time
this.myField.DoSomething();

It' s хороший, чтобы аннулировать область после расположения его и разобраться в NullPtrEx в линии, где область используется снова. Иначе Вы могли бы столкнуться с некоторой загадочной ошибкой в конечном счете (в зависимости от точно, что DoSomething делает).

Комментарии (2)

Также:

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of
Комментарии (0)

Возможности состоят в том, что Ваш кодекс не структурирован достаточно плотно, если Вы чувствуете потребность к 'null ' переменные.

Есть много способов ограничить объем переменной:

Как упомянуто Стив Трэнби

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of

Точно так же Вы можете просто использовать вьющиеся скобки:

{
    // Declare the variable and use it
    SomeObject object = new SomeObject()
}
// The variable is no longer available

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

Комментарии (2)

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

Комментарии (2)

В целом никакая потребность установить в пустой указатель. Но предположите, что у Вас есть функциональность Сброса в Вашем классе.

Тогда Вы могли бы сделать, потому что Вы не хотите звонить, располагают дважды, так как часть Расположения не может быть осуществлена правильно и Система броска. Исключение ObjectDisposed.

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }
Комментарии (1)

этот вид " нет никакой потребности установить объекты аннулировать после use" не совсем точно. Есть времена, Вы должны АННУЛИРОВАТЬ переменную после расположения его.

Да, Вы должны ВСЕГДА называть '.Dispose ()' или '.Close ()' на чем-либо, у чего есть он, когда Вы сделаны. Будьте им дескрипторы, соединения с базой данных или доступные объекты.

Отдельный от этого очень практический образец LazyLoad.

Скажите, что я имею и иллюстрировал примерами 'ObjA' 'класса A'. У 'Класса A' есть общественная собственность под названием 'PropB' 'класса B'.

Внутренне, 'PropB' использует частную переменную '_B' и дефолтов к пустому указателю. То, когда 'PropB.Get ()' используется, он проверяет, чтобы видеть, пустой ли '_PropB' и если это, открывается, ресурсы должны были иллюстрировать примерами 'B' в '_PropB'. Это тогда возвращает '_PropB'.

К моему опыту это - действительно полезная уловка.

То, где потребность аннулировать входит, - то, если Вы перезагрузите или изменитесь в некотором роде, что содержание '_PropB' было ребенком предыдущих значений, Вы должны будете Расположить И пустой указатель '_PropB', таким образом, LazyLoad сможет перезагрузить, чтобы принести правильную стоимость, ЕСЛИ кодекс требует его.

Если Вы только делаете '_PropB.Dispose ()' и вскоре после того, как будут ожидать, что пустая проверка на LazyLoad будет иметь успех, это won' t быть пустым, и you' ll посмотреть на устаревшие данные. В действительности Вы должны аннулировать его после того, как 'Расположат ()' только, чтобы быть уверенным.

Я верное желание это было иначе, но I' ve получил кодекс прямо сейчас, показывающий это поведение после того, как 'Располагают ()' на '_PropB' и за пределами функции запроса, которая сделала Расположение (и таким образом почти из объема), частная опора все еще isn' t пустой указатель и устаревшие данные все еще там.

В конечном счете склонная собственность аннулирует, но that' s недетерминированный с моей точки зрения.

Основная причина, как dbkk ссылается, то, что родительский контейнер ('ObjA' с 'PropB') держит случай '_PropB' в объеме, несмотря на 'Располагают ()'.

Комментарии (1)

Стивен Клири объясняет очень хорошо на этой почте: Я должен Установить Переменные в Пустой указатель Помогать Сборке мусора?

Говорит:

короткий ответ, для нетерпеливого Да, если переменная - статическая область, или если Вы пишете счетный метод (использующий возвращение урожая) или асинхронный метод (использующий async, и ждите). Иначе, нет.

Это означает, что в обычных методах (несчетный и неасинхронный), Вы не устанавливаете местные переменные, параметры метода или области случая к пустому указателю.

(Даже если Вы осуществляете IDisposable. Расположите, Вы все еще не должны устанавливать переменные в пустой указатель).

Важная вещь, которую мы должны рассмотреть, Статические Области .

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

Урегулирование статических областей к пустому указателю бессмысленно, если весь процесс закрывается. Вся куча собирается быть мусором, собранным в том пункте, включая все объекты корня.

Заключение:

Статические области ; это об этом. Что-либо еще пустая трата времени .

Комментарии (0)

Смотрите на эту статью также: http://www.codeproject.com/KB/cs/idisposable.aspx

По большей части урегулирование объекта аннулировать не имеет никакого эффекта. Единственное время, которое Вы, несомненно, должны будете сделать так, - то, если Вы работаете с " большой object" который является одним большим, чем 84K в размере (таком как битовые массивы).

Комментарии (0)

Есть некоторые случаи, где это имеет смысл к нулевым ссылкам. Например, когда you' ре сочиняя коллекцию - как приоритетная очередь - и согласно Вашему контракту, Вы shouldn' t поддержать те объекты для клиента после того, как клиент удалил их из очереди.

Но этот вид вещи только имеет значение в долговечных коллекциях. Если queue' s не собирающийся переживать конец функции это было создано в, тогда это имеет значение намного меньше.

На целом, Вы действительно shouldn' t беспокойство. Позвольте компилятору, и GC делают их работы, таким образом, Вы можете сделать Ваши.

Комментарии (0)

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

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

Комментарии (0)

Я верю дизайном конструкторов GC, Вы can' t < b> скорость up GC с нуллификацией. I' m верный they' d предпочитают, чтобы Вы не взволновали себя с тем, как/когда GC бежит - рассматривают его как этот повсеместный < b> Being защищая и следя и для Вас... (склоняет голову вниз, поднимает кулак до неба)...

Лично, я часто явно установил переменные в пустой указатель когда I' m сделанный с ними как форма сам документация. Я don' t объявляют, используют, затем устанавливают в пустой указатель позже - я немедленно аннулирую после they' ре больше не необходимо. I' m высказывание, явно, " I' m официально сделанный с Вами... закончиться..."

Аннулирует необходимый в GC' d язык? Нет. Действительно ли это полезно для GC? Возможно, да, возможно, не, don' t знают наверняка дизайном I действительно can' t управляют им, и независимо от today' s отвечают этой версией или что, будущие внедрения GC могли изменить ответ вне моего контроля. Плюс то, если/когда аннулирование оптимизировано it' s немного больше, чем воображение < i> comment если Вы будете.

Я фигурирую, делает ли это мое намерение более ясным следующему бедному дураку, который идет по моим стопам, и если это < i> " might" потенциально помогайте GC иногда, тогда it' s стоящий того мне. Главным образом это заставляет меня чувствовать себя опрятным и ясным, и монго нравится чувствовать себя опрятным и ясным.:)

Я смотрю на него как это: Языки программирования существуют, чтобы позволить людям дать другим людям общее представление намерения и компилятора запрос работы того, что сделать - новообращенные компилятора, которые просят на различный язык (иногда несколько) для центрального процессора - центральный процессор (процессоры) мог дать крик, какой язык Вы использовали, Ваши параметры настройки счета, комментарии, стилистические акценты, имена переменной, и т.д. - CPU' s все о битовом потоке, который говорит ему что регистры и opcodes и местоположения памяти вертеть. Много вещей, написанных в кодексе don' t преобразовывают в what' s потребляемый центральным процессором в последовательности мы определили. Наш C, C ++, C#, Шепелявость, Столпотворение, ассемблер или независимо от того, что теория, а не действительность, письменная как заявление работы. То, что Вы видите, не то, что Вы получаете, да, даже на языке ассемблера.

Я действительно понимаю мышление " ненужный things" (как пустые строки) " только шум и загромождает кодекс " Это было я ранее в моей карьере; я полностью получаю это. В данный момент я склоняюсь к этому, которое делает кодекс более четким. It' s не как I' m добавляющий даже 50 линий " noise" к моим программам - it' s несколько линий здесь или там.

Есть исключения к любому правилу. В сценариях с изменчивой памятью, статической памятью, условиями гонки, единичными предметами, использованием " stale" данные и вся такая гниль, that' s отличающийся: Вы ДОЛЖНЫ управлять своей собственной памятью, захватывая и аннулируя как кстати, потому что память не часть GC' d Вселенная - надо надеяться, все понимают это. Остальная часть времени с GC' d языки it' s вопрос стиля, а не необходимости или гарантируемого исполнительного повышения.

В конце дня удостоверяются, что Вы понимаете то, что имеет право на GC и what' s нет; захватите, расположите и аннулируйте соответственно; воск на, воск прочь; сделайте вдох, сделайте выдох; и для всего остального я говорю: Если это чувствует себя хорошо, сделайте это. Ваш пробег может измениться..., как он должен...

Комментарии (0)

Некоторый объект предполагает метод .dispose(), который заставляет ресурс быть удаленным из памяти.

Комментарии (2)