Когда расположены элементы управления asp.net - PullRequest
2 голосов
/ 15 октября 2011

Я охотюсь на утечки памяти на сайте asp.net. Я обнаружил, что код не выпускает обработчики событий, когда элементы управления больше не нужны. Я использовал шаблон удаления, как показано в MSDN, чтобы очистить их, и поместил вызовы для удаления обработчиков событий внутри блока if (disposing), поскольку они были управляемыми ресурсами, но если я не пройду и не добавлю деструкторы на каждую страницу и получу их все вручную располагают элементы управления, ничего не срабатывает, пока финализатор не уберет беспорядок. Делать это таким образом было бы хрупко и сделать повторную утечку в будущем относительно легкой; было бы лучше проигнорировать соглашение о том, чтобы не касаться неуправляемых объектов в коде, запущенном финализатором?

// Design pattern for a base class.
public class Base: IDisposable
{
   //Implement IDisposable.
   public void Dispose() 
   {
     Dispose(true);
      GC.SuppressFinalize(this); 
   }

   protected virtual void Dispose(bool disposing) 
   {
      if (disposing) 
      {
         myControl.SomeEvent -= SomeEventHandler;
         // Free other state (managed objects).
      }
      // Free your own state (unmanaged objects).
      // Set large fields to null.
   }

   // Use C# destructor syntax for finalization code.
   ~Base()
   {
      // Simply call Dispose(false).
      Dispose (false);
   }
}

Ответы [ 3 ]

2 голосов
/ 15 октября 2011

Когда расположены элементы управления asp.net

Никогда, если есть живая ссылка.

Вызов метода Dispose рекомендуется, если у вас есть Disposable Объекты. Если вы просто позволите им выйти из области видимости, они будут добавлены в очередь завершения в первом цикле сбора мусора. И освободит память во втором цикле сборки мусора после завершения. Финализация - это нежелательные накладные расходы, если вы можете вызвать метод Dispose и SuppressFinalization.

И другая вещь в вашем примере кода. Наличие метода Finalize без какого-либо неуправляемого кода. Если вы посмотрите на путь выполнения Finalize-> Dispose (false), вы заметите, что он ничего не делает. Потому что все управляемые объекты обрабатываются только если disposing. Поэтому нет смысла добавлять метод Finalize, если у вас нет неуправляемых объектов.

Объект будет добавлен в очередь завершения и вызовет метод Finalize, только если этот объект не имеет живых ссылок (в первом цикле GC). Так что вы обязаны отменить регистрацию необходимых событий. В противном случае Finalize никогда не будет выполняться, пока есть ссылка на этот объект.

Вот хороший справочник по отмене регистрации обработчиков событий.

Необходимо ли явно удалять обработчики событий в C #

1 голос
/ 15 октября 2011

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

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

1 голос
/ 15 октября 2011

единственный раз, когда вам нужно прикоснуться к нему, это когда вы хотите, чтобы он был очищен СЕЙЧАС

Или если вы собираетесь войти в блок, который создает много объектов.

В противном случае - пусть GC решит.

ps, почему вы не используете механизм USING?

...