.NET очень эффективно справится со сборкой мусора. Хотя для типов, реализующих IDisposable
, целесообразно вызывать метод Dispose
, это, вероятно, не ваша проблема. Утечки памяти могут происходить в .NET по многим причинам. Вот некоторые из них:
- Вы кэшируете слишком много данных на пользователя в сеансе.
- Вы кэшируете слишком много данных на уровне приложения в кэше приложения или в статической переменной, такой как словарь.
- Вы храните веб-элементы управления (или пользовательские элементы управления) на уровне сеанса или приложения.
- Вы привязываете экземпляры к событиям статических типов или к типам, на которые продолжают ссылаться (потому что они хранятся в кэше).
Надеюсь, это даст вам представление о том, где искать.
ОБНОВЛЕНИЕ: Вы должны посмотреть это видео об отладке ASP.NET.
ОБНОВЛЕНИЕ 2:
По поводу вашего комментария мой ответ следующий.
CLR соберет всю управляемую память, поэтому будут собраны все объекты, которые вы создаете с помощью new
. В этом смысле не имеет значения, реализует ли объект IDisposable
или нет. Однако во многих случаях вам необходимо прямо или косвенно использовать собственные ресурсы (такие как дескрипторы файлов, графические дескрипторы, соединения с базой данных, использование собственной неуправляемой памяти). CLR не знает, как освободить эти ресурсы. Для этого в .NET есть понятие финализаторов. Финализатор - это виртуальный метод, который может реализовать разработчик класса. Когда вы сделаете это, CLR вызовет этот метод после того, как экземпляр этого типа станет не связанным, и до того, как он будет собран. Финализаторы обычно содержат логику, которая освобождает эти ресурсы. Другими словами, когда типу нужны собственные ресурсы, он обычно имеет метод финализатора, который позволяет типу освобождать эти ресурсы.
Что касается CLR, история заканчивается здесь. В CLR нет специальной обработки объектов, которые реализуют интерфейс IDisposable
. Однако сборщик мусора в .NET недетерминирован по своей природе. Это означает, что вы не знаете, когда он работает и работает ли он. Это означает, что может пройти очень много времени, прежде чем ваши родные ресурсы будут очищены (потому что финализатор будет вызываться только после сбора). Однако для многих ресурсов необходимо освободить их, как только вы закончите с ними. Например, вы стремитесь быстро исчерпать соединения с базой данных, когда не закрываете их или когда вы работаете с GDI + в .NET через пространство имен System.Drawing).
По этой причине был введен интерфейс IDisposable
. Опять же, CLR и сборщик мусора не смотрят на этот интерфейс. Это контракт между типом и его пользователями, позволяющий пользователям напрямую высвобождать базовые ресурсы объекта. В нормальном дизайне и финализатор объекта, и метод Dispose
объекта будут вызывать один и тот же закрытый или защищенный метод, который освободит эти ресурсы. Когда тип реализует IDisposable
, разумно будет вызывать его метод Dispose
, когда вы покончили с ним, или обернуть объект в оператор using
, чтобы разрешить освобождение собственных ресурсов.
Итак, вернемся к вашему вопросу. Все управляемые объекты будут собраны GC, а собственные ресурсы - нет. Поэтому типы могут реализовывать метод финализатора, и эти объекты также обычно реализуют интерфейс IDisposable
. Вызов Dispose
для них явно и напрямую освободит эти собственные ресурсы.
Надеюсь, это имеет смысл.