После безуспешного поиска утечек
Попробуй сильнее =)
Утечки памяти на управляемом языке могут быть сложными, чтобы отследить. У меня был хороший опыт работы с Redgate ANTS Memory Profiler . Это не бесплатно, но они дают вам 14-дневную полнофункциональную пробную версию. Он имеет приятный пользовательский интерфейс и показывает, где находится ваша память и почему эти объекты хранятся в памяти.
Как говорит Алекс, обработчики событий являются очень распространенным источником утечек памяти в приложении .NET. Учтите это:
public static class SomeStaticClass
{
public event EventHandler SomeEvent;
}
private class Foo
{
public Foo()
{
SomeStaticClass.SomeEvent += MyHandler;
}
private void MyHandler( object sender, EventArgs ) { /* whatever */ }
}
Я использовал статический класс, чтобы сделать проблему как можно более очевидной. Допустим, в течение жизни вашего приложения создается много объектов Foo
. Каждый Foo
подписывается на событие SomeEvent
статического класса.
Объекты Foo
могут время от времени выпадать из области видимости, но статический класс поддерживает ссылку на каждый из них через делегат обработчика событий. Таким образом, они сохраняются живыми до бесконечности. В этом случае обработчик событий просто необходимо отключить.
... проект XNA, похоже, сохранил много байтовых массивов, которые я действительно использовал ...
Вы можете столкнуться с фрагментацией в LOH. Если вы выделяете большие объекты очень часто, они могут быть причиной проблемы. Общий размер этих объектов может быть намного меньше, чем общий объем памяти, выделенный для среды выполнения, но из-за фрагментации много неиспользуемой памяти выделяется для вашего приложения.
Профилировщик, на которого я ссылался выше, сообщит вам, если это проблема. Если это так, вы, вероятно, сможете отследить его до утечки объекта где-нибудь. Я только что исправил проблему в моем приложении, показывающую то же поведение, и это было из-за того, что MemoryStream
не выпускал свой внутренний byte[]
даже после вызова Dispose()
для него. Оборачивание потока в фиктивный поток и обнуление его решило проблему.
Также, указав очевидное, убедитесь, что Dispose()
ваших объектов, которые реализуют IDisposable
. Там могут быть местные ресурсы валяются. Опять же, хороший профилировщик поймает это.
Мое предложение; это не GC, проблема в вашем приложении. Используйте профилировщик, приведите ваше приложение в состояние высокого потребления памяти, сделайте снимок памяти и начните анализ.