Каков ваш список «Осторожно» относительно предотвращения утечек памяти при написании кода .NET? - PullRequest
10 голосов
/ 31 октября 2008

Что вы помните, чтобы избежать утечек памяти при написании тысяч строк кода .NET? Я большой поклонник предотвращения проверок, есть известный пример относительно этого пункта, который использует «StringBuilder» для объединения строк вместо «String1 + String2», так что еще из вашего опыта кодирования?

Заранее спасибо за то, что поделились своими мыслями.

Ответы [ 9 ]

12 голосов
/ 31 октября 2008

События. Всегда отписываться от событий, это единственная функция, обеспечивающая утечку .NET.

Подписка на событие означает «уведомлять и удерживать меня, пока вы живы», а не «уведомлять меня, пока я жив». Отказ от подписки на событие обычно приводит к большим кластерам висящих объектов, особенно в пользовательском интерфейсе.

6 голосов
/ 31 октября 2008

установить корневые ссылки на null после использования.

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

5 голосов
/ 31 октября 2008

Убедитесь, что вы всегда располагаете IDisposable объектами. Кроме того, старайтесь всегда использовать блоки «using (...)» для объявления одноразовых объектов.

3 голосов
/ 31 октября 2008

Знайте всю сложность всего, что вы делаете, насколько это возможно, и думайте о каждой ситуации, а не полагайтесь на догму. Например, помните, что с использованием StringBuilder не всегда является правильным способом объединения строк :)

Там, где это возможно, старайтесь выполнять потоковую передачу данных, а не буферизировать их - здесь нужно быть осторожным, когда речь идет о LINQ to Objects, понимая, какие операторы буферизуют и какой поток (и которые выполняют оба с разными последовательностями).

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

2 голосов
/ 31 октября 2008

Не совсем утечка памяти, но одна вещь, которая всегда меня заводит:

Всегда Закройте ваши SQL-соединения после их использования.

2 голосов
/ 31 октября 2008

Каждый DataTable.NewRow () должен иметь соответствующий DaraTable.Rows.Add (...).

1 голос
/ 31 октября 2008

Если используется COM-взаимодействие, используйте Marshal.ReleaseComObject после того, как вы закончили с COM-объектом, чтобы освободить Runtime Callable Wrapper (RCW).

Кроме того, если ваш COM-объект имеет свойство или метод, который возвращает другой COM-объект, позаботьтесь о том, чтобы всегда присваивать его переменной и впоследствии освобождать.

т.е. это приведет к утечке объекта, полученного GetFirstChild:

string name = myBigComObject.GetFirstChild().Name;

Использование istead:

ChildComObject firstChild = myBigComObject.GetFirstChild()
string name = firstChild.Name;
Marshal.ReleaseComObject(firstChild);
1 голос
/ 31 октября 2008

Специфично для .NET Компакт Framework: вам нужно явно расположить все связанные с графикой объекты (Graphics, Pen, SolidBrush, Bitmap), иначе они будут зависать в памяти (не очень хорошо, когда вы работаете с устройствами с малым объемом памяти).

1 голос
/ 31 октября 2008
something.someEvent += new EventHandler(memoryhog.someMethod);
[...]
something.someEvent += new EventHandler(memoryhog.someMethod);
[...]
something.someEvent -= new EventHandler(memoryhog.someMethod);

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

В библиотеке Managed DirectX была такая ошибка, которая приводила к большим утечкам памяти.

...