выделение памяти c# и шаблоны освобождения

Так как C# использует Сборку "мусора". Когда необходимо использовать.Dispose для освобождения памяти?

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

  1. Если я закрываю Форму, которая содержит текстовый объект GUI, те объекты разыменовываются и поэтому будут собраны?
  2. Если я создаю локальный объект, использующий новый, должен я.Dispose его перед выходами метода или просто позволить GC заботиться о нем? Что такое хорошая практика в этом случае?
  3. Есть ли какие-либо времена, в которые принуждение GC понятно?
  4. События собраны GC, когда это - объект, собран?
8
задан Neal 27 April 2010 в 00:09
поделиться

5 ответов

Теоретически, если вы правильно определили компоненты, никогда не должно требоваться вызывать Dispose () для ваших объектов, как это должен делать финализатор в конце концов позаботится об этом.

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

По некоторым конкретным вопросам:

1) Если вы знаете, что «закончили» с формой, вы можете вызвать для нее Dispose (). Это вызовет очистку в этот момент неуправляемых ресурсов, связанных с формой.

2) В этом случае: если ваш объект просто используется в этом методе, используйте вместо этого «using»:

using (MyObject myObject = new MyObject())
{
   // use your object
} // It'll be disposed of here for you

3) Есть редкие причины для этого, но в целом нет.

4) События являются делегатом - память, связанная с делегатом, будет собрана после того, как сам делегат станет некорневым, что обычно происходит, когда рассматриваемые объекты не имеют root-доступа.

10
ответ дан 5 December 2019 в 10:39
поделиться

Вы должны вызвать Dispose для каждого класса, реализующего IDisposable . Если бы его не нужно было Dispose , то он не реализовал бы IDisposable .

Что касается других ваших вопросов:

  1. Когда вы добавляете элемент управления в коллекцию Controls формы, то этот элемент управления будет автоматически удален при закрытии формы, поэтому вам ничего не нужно там делать .
  2. Если объект реализует IDisposable , необходимо вызвать Dispose . Например, если вы перейдете к new FileStream (...) , то нужно удалить FileStream, поскольку он реализует IDisposable. Я предлагаю вам ознакомиться с конструкцией using в C #, которая упрощает работу с объектами IDisposable .
  3. Нет, в 99,99% случаев сборщик мусора знает, когда лучше всего запускаться. Это одна из тех ситуаций, когда «ты узнаешь, когда тебе это понадобится».
  4. Когда на объект, содержащий событие, больше не ссылаются, то логически любые ссылки на объекты, содержащиеся в событии, также больше не упоминаются и будут доступны для сбора.
3
ответ дан 5 December 2019 в 10:39
поделиться

Если вы используете объект IDisposable , рассмотрите возможность использования оператора using для автоматической обработки удаления для ты.

0
ответ дан 5 December 2019 в 10:39
поделиться

Посмотрите на этот вопрос:

Есть ли общепринятая практика, как упростить освобождение памяти для сборщика мусора в .NET?

Если ваш класс создает экземпляр интерфейса IDisposable, это (вероятно) означает, что у него есть система ресурсы, которые необходимо утилизировать напрямую. Один из простых способов добиться этого - использовать ключевое слово using, например:

using(var g = Graphics.FromBitmap(bmp))
{
    //Do some stuff with the graphics object
}

на ответ @Matt S в том вопросе, на который я ссылался.

На ваши вопросы:

  1. Если вы создаете экземпляр объекта с IDisposable, вам нужно будет удалить его при закрытии формы. Это сложно в WPF и просто в Winforms, поскольку диалоговые окна winforms имеют методы Dispose. Для WPF я решил проблему, сохранив класс WPF, но скрытый, вызвав метод удаления, который удаляет все объекты (например, последовательные порты), а затем устанавливает для класса WPF значение null.
  2. Нет. Пусть об этом позаботится сборщик мусора.
  3. Думаю, да, но я получил отрицательные голоса :) Когда я сделал очень большие выделения, принудительное удаление их из GC - хорошая идея.
  4. Я не уверен. Я думаю, что события сами по себе являются объектами, поэтому они будут собираться, когда больше не используются.
2
ответ дан 5 December 2019 в 10:39
поделиться

Как сказал Рид Копси, обычно нет необходимости вызывать Dispose.

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

Form_Load(...)
    MyState.Instance.AddressChanged += this.User_AddressChanged;
End

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

1
ответ дан 5 December 2019 в 10:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: