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

голоса
173

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

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

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

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

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

Задан 05/08/2008 в 21:14
источник пользователем
На других языках...                            


13 ответов

голоса
66

Карл абсолютно правильно, нет необходимости устанавливать объекты в нуль после использования. Если объект реализует IDisposable, просто убедитесь , что вы звоните , IDisposable.Dispose()когда вы закончите с этим объектом (завернутым в try.. finally, или, в using()блоке). Но даже если вы не помните назвать Dispose()метод finaliser на объекте должен быть вызовом Dispose()для вас.

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

Порывшись в IDisposable

и это

Понимание IDisposable

Существует нет смысла пытаться вторым угадать GC и его стратегию управления , потому что это автоматическая настройка и непрозрачная. Был хороший разговор о внутренней работе с Джеффри Рихтером на Dot Net Rocks здесь: Джеффри Рихтер на модели памяти Windows и Richters книги CLR через C # глава 20 имеет большое лечение:

Ответил 05/08/2008 в 21:56
источник пользователем

голоса
33

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

например

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;
}

может иногда держать объект живым до конца этого метода. JIT обычно оптимизируется прочь задание NULL , поэтому оба бита кода в конечном итоге то же самое.

Ответил 15/08/2008 в 15:43
источник пользователем

голоса
15

Нет не нулевые объекты. Вы можете проверить http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx для получения дополнительной информации, но установка вещи в нуль не будет делать ничего, кроме грязного кода.

Ответил 05/08/2008 в 21:23
источник пользователем

голоса
7

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

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

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

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

Ответил 09/08/2008 в 12:16
источник пользователем

голоса
7

Также:

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of
Ответил 05/08/2008 в 21:37
источник пользователем

голоса
6

Скорее всего , что ваш код не структурирован достаточно плотно , если вы чувствуете потребность в nullпеременных.

Есть несколько способов, чтобы ограничить область действия переменной:

Как отметил Стив Tranby

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

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

Ответил 09/08/2008 в 13:13
источник пользователем

голоса
5

В общем нет необходимости устанавливать на нуль. Но предположим, что у вас есть Reset функциональность в своем классе.

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

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }
Ответил 17/04/2012 в 09:55
источник пользователем

голоса
4

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

Ответил 05/08/2008 в 21:32
источник пользователем

голоса
3

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

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

Отдельно от который является очень практичной картиной LazyLoad.

Скажем , у меня есть и экземпляры ObjAиз class A. Class Aимеет общественное свойство PropBиз class B.

Внутренне PropBиспользует частные переменные _Bи по умолчанию NULL. Когда PropB.Get()используется, он проверяет, _PropBявляется недействительным , и если она есть, открывает ресурсы , необходимые для создания экземпляра BINTO _PropB. Затем он возвращается _PropB.

К моему опыту, это очень полезный трюк.

В случае , если необходимость нуль приходит, если вы сбросить или изменить каким - то образом , что содержание _PropBбыли ребенком предыдущих значений A, вам нужно будет утилизировать и обнулять _PropBтак LazyLoad можно сбросить , чтобы принести правильное значение , если код требует.

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

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

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

Основная причина, так как dbkk намекает, что родительский контейнер ( ObjAс PropB) держит экземпляр _PropBв объеме, несмотря на Dispose().

Ответил 11/04/2012 в 02:12
источник пользователем

голоса
1

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

По большей части, установка объекта в нуль не имеет никакого эффекта. Единственный раз, когда вы должны быть уверены, чтобы сделать это, если вы работаете с «большой объект», который один больше, чем 84K в размере (например, растровых изображений).

Ответил 17/08/2008 в 05:46
источник пользователем

голоса
1

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

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

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

Ответил 05/08/2008 в 21:46
источник пользователем

голоса
0

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

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

Является ли уничтожение необходимости в языке GC'd? Нет . Это полезно для GC? Может быть , да, может быть , нет, не знаю наверняка, дизайном я действительно не могу контролировать его, и независимо от сегодняшнего ответа с этой версией , или что будущие реализации GC могут изменить ответ вне моего контроля. Кроме того, если / когда обнулением оптимизирован из это немного больше , чем фантазии комментарий , если вы будете.

Я полагаю , что если это делает мое намерение понятнее следующего бедного дурака , который следует по моим стопам, и если это «может» потенциально помочь GC иногда, то это стоит мне. В основном это заставляет меня чувствовать себя аккуратно и ясно, и Монго любит чувствовать себя аккуратно и ясно. :)

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

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

Есть исключения из любого правила. В сценариях с энергонезависимой памятью, статической памяти, условия гонки, одиночек, использование «несвежих» данных и все такого рода гнили, что по-другому: вам нужно управлять собственной памяти, блокировки и сводит на нет, как Apropos, потому что память не является частью GC'd Universe - надеюсь, все понимают, что. Остальная часть времени с GC'd языков это вопрос стиля, а не необходимость или гарантированного повышения производительности.

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

Ответил 10/05/2016 в 13:07
источник пользователем

голоса
-1

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

Ответил 05/08/2008 в 21:21
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more