Какие переменные должны быть расположены? (.NET / Java) - PullRequest
4 голосов
/ 15 августа 2010

Три вопроса:

  1. Какие переменные должны быть расположены вручную в .NET / Java? Я знаю, что SqlConnection всегда следует либо удалять вручную, либо использовать в блоке using {}. Это правильно? Какие еще виды переменных должны быть расположены?

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

  3. Наконец, как мне расположить переменные? Я знаю, что метод Dispose () на самом деле не располагает переменной. Так что же делает Dispose ()? Должен ли я установить их в null ()? По какой логике работает сборщик мусора?

Ответы [ 8 ]

5 голосов
/ 15 августа 2010

Этот ответ касается только части .NET вашего вопроса

Какие переменные должны быть расположены вручную в .NET / Java?Я знаю, что SqlConnection всегда следует либо удалять вручную, либо использовать в блоке using {}.Это правильно?Какие еще виды переменных должны быть расположены?

В .NET все объекты, которые реализуют IDisposable, должны быть расположены явно (или использоваться в блоке using).

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

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

Наконец, как мне это сделать?распоряжаться переменными?Я знаю, что метод Dispose () на самом деле не располагает переменной.Так что же делает Dispose ()?Должен ли я установить их в null ()?По какой логике работает сборщик мусора?

Я не уверен, что понимаю ваш вопрос ... вы не располагаете переменной, она управляется сборщиком мусора.Вся управляемая память автоматически освобождается, когда она больше не используется (т.е. она недоступна для кода, потому что на нее не осталось ссылок).Метод IDisposable.Dispose предназначен только для ресурсов, которые не управляются GC.


РЕДАКТИРОВАТЬ: в качестве примечания я хотел бы добавить, что IDisposable - это в основном предназначен для очистки неуправляемых ресурсов, но также часто используется для выполнения других действий по очистке и обеспечения целостности состояния или данных.Например, IDbTransaction реализует IDisposable для отката транзакции, если перед выполнением транзакции возникает исключение:

using (var trx = connection.BeginTransaction())
{
    // Do some work in the transaction
    ...

    // Commit
    trx.Commit();

} // the transaction is implicitly rolled back when Dispose is called
4 голосов
/ 15 августа 2010

В Java вы «закрываете», а не «утилизируете».

  • Соединения JDBC, если вы не получили их из пула.
  • JDBC ResultSets, в зависимости от разъема JDBC.
  • InputStreams, OutputStreams, Readers и Writers (за исключением тех, которые являются байтовым массивом и строковой поддержкой).

Некоторые сторонние библиотеки или фреймворки Java имеют классы, которые необходимо удалять / закрывать / уничтожать вручную.

2 голосов
/ 15 августа 2010

.NET

  1. Все объекты, которые реализуют интерфейс IDisposable , требуют, чтобы их методы Dispose вызывались, когда они больше не нужны.Блок using является просто C # сахаром для блока try-finally, который располагает IDiposable в блоке finally, если он не равен нулю.Следовательно, удаление происходит, даже если в блоке try выдается исключение.

  2. Неуправляемый код .

  3. The *Метод 1020 * делает любой код, который вложил в него разработчик, который написал метод Dispose!Обычно это включает в себя высвобождение «неуправляемых» ресурсов, которые не управляются средой выполнения, таких как соединения с базой данных, дескрипторы окон и дескрипторы файлов.Обратите внимание, что GC управляет кучей, поэтому установка ссылки на ноль непосредственно перед тем, как объект, на который он ссылается, становится недостижимым, не очень помогает..

1 голос
/ 16 августа 2010

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

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

Это редко полезно, например, или статическоечлены, так как память не так ценен как ресурс, как часто думают люди ( - это драгоценный ресурс, но большинство попыток разобраться с ним в нескольких строках кода похоже на отключение ваших нажатий, пока вы 've the burst main.

Хотя это полезно, если у вас есть статический член или член экземпляра класса и (A) это большой объект (B) объект-владелец, скорее всего, останется в памяти длядолгое время и (C) вы знаете, что вам не понадобится этот прирост значения, чтобы установить для этого члена значение null.

На практике это не очень распространенная комбинация. Если вы сомневаетесь, просто оставьте в покое.

Теперь прочитайте другие ответы здесь, поскольку то, что они говорят о методе Dispose (), гораздо важнее.

1 голос
/ 15 августа 2010

Если .net, если вы можете использовать объект в операторе «using», это означает, что объект реализует iDisposable, и вы должны, когда это возможно, вызывать его метод удаления, когда вы закончите с ним.Обратите внимание, что метод удаления не всегда может называться «Dispose», но вы всегда можете вызвать его, приведя объект к iDisposable и затем вызвав Dispose для этого.

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

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

1 голос
/ 15 августа 2010

Отслеживание других решений .NET ...

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

  1. Добавить финализатор для класса.
  2. Добавьте публичное свойство bool с именем Disposed, которое указывает, что объект был удален.
  3. Добавить защищенный метод удаления (bool). Открытый метод Dispose () не имеет параметров.
  4. При вызове Dispose (), если свойство Disposed имеет значение false, оно вызовет Dispose (true) и вызовет GC.SuppressFinalize () для отключения финализатора. Это важно, чтобы сборщик мусора в .NET был доволен. Классы с неотжатыми финализаторами идут в конец строки для очистки сборщика мусора, поэтому они становятся почти утечкой памяти.
  5. Затем открытый метод Dispose () должен установить для свойства Disposed значение true.
  6. Финализатор вызывает Dispose (false).
  7. Dispose (bool) всегда будет очищать свои собственные управляемые ресурсы, но он будет очищать неуправляемые ресурсы только при вызове Dispose (true). Обратите внимание, что очистка ресурса all осуществляется в защищенном методе Dispose (bool), а не в открытом методе Dispose ().
  8. Если класс не запечатан, то защищенный метод Dispose (bool) должен быть виртуальным. Подклассы, которые должны выполнить очистку, могут переопределить Dispose (bool) и следовать той же логике, что и выше. Кроме того, они должны вызывать base.Dispose (bool) с параметром, который им был задан.
1 голос
/ 15 августа 2010

для Java:

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

1 голос
/ 15 августа 2010

Это было в основном покрыто Томасом, но для расширения на третий пункт:

Наконец, как мне расположить переменные? Я знаю, что Dispose () метод на самом деле не располагает переменная. Так что же делает Dispose ()? Должен ли я установить их в null ()? Что такое логика, по которой мусор коллектор работает?

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

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

...