Каков ваш список "Остерегайтесь", чтобы избежать утечки памяти при написании кода .NET?

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

заблаговременно за то, что разделили свои мысли.

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

something.someEvent += new EventHandler(memoryhog.someMethod);
[...]
something.someEvent += new EventHandler(memoryhog.someMethod);
[...]
something.someEvent -= new EventHandler(memoryhog.someMethod);

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

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

Ответ 8

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

Ответ 9

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

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

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

string name = myBigComObject.GetFirstChild().Name;

Использовать istead:

ChildComObject firstChild = myBigComObject.GetFirstChild()
string name = firstChild.Name;
Marshal.ReleaseComObject(firstChild);