Использование памяти .NET приложения растет со временем, утечка памяти или нет? - PullRequest
1 голос
/ 19 октября 2010

Я написал .NET-приложение, в котором использование памяти растет со временем.В качестве теста я настроил его на загрузку файлов размером 800 * 5K (среднего) и преобразование XML и использование DTComcontroller для генерации манифеста в течение 1 часа с интервалом в 15 минут.В течение примерно 5 часов объем используемой памяти увеличивается с 35 до 70 млн.

Не уверен, нормально это или нет.Я уже заставляю это делать

GC.collection();
GC.WaitForPendingFinalizers();

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

Я уже проверяю закрытие дескриптора файла, очисткапоток или другие ресурсы после его использования.И некоторые объекты просто используют локальные ссылки внутри функции, и я предполагаю, что они будут отброшены в конце локальной функции и уйдут с GC.collction ().

Также Memory Profiler (ANTS) показывает, что естьне осталось объектов с пространством имен моего приложения в конце каждого рабочего круга, а также не осталось новых объектов с доступным исходным кодом.Новые экземпляры объектов, создаваемых во время каждого рабочего цикла, в основном называются RuntimeModule, RuntimeAssembly и DeviceContext.Похоже, я ничего не могу с этим поделать?

По сути, это мое первое приложение, которое должно работать 24/7, и я действительно мало что знаю о утечке памяти.Скорее всего, в моем приложении все еще есть проблемы с использованием памяти.Я просто не знаю, где искать этот этап.

Кроме того, я не знаю, связано это или нет, я использую .net Trace / debug для ведения журнала.Думаю, стоит попытаться отключить журнал, чтобы увидеть рост использования памяти.

Обновление: alt text Доза выглядит как круговая ссылка sslstate и sslstream, а также других классов в классе Reference Explorer.Также не уверен, что это круговая ссылка в сгенерированном графе ANTS, это означает, что в моем коде где-то есть круговая ссылка?

Я сделал несколько изменений, повторно используя один и тот же объект для создания XMLtransform и Manifest, и вручнуюустановите каждый объект равным нулю после окончания использования их в конце рабочей итерации.Теперь память значительно уменьшена, все еще увеличивается использование частной памяти, поскольку она работает, но очень медленно.

Я думаю, что для моего конкретного случая - создайте много объектов внутри рабочего круга, и все данные будут храниться врабочая нить.Если я не освобождаю ссылки на объекты в явном виде, пусть .NET GC сделает это, что приведет к большому объему памяти, используемой приложением, поскольку оно продолжает работать большую часть времени, и GC, возможно, никогда не получит шанс заняться домашним хозяйством, если толькоприложение было закрыто вручную, я должен сделать выпуск объекта намного более вручную.
@WeNeedAnswers:

            XmlDocument doc = new XmlDocument();
            XmlTextReader textReader = new XmlTextReader(dataFile);
            textReader.Read();
            doc.Load(textReader);

Ответы [ 4 ]

2 голосов
/ 20 октября 2010

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

Если вместо этого вы посмотрите на «Частные байты», используемые вашим процессом, это должно дать вам лучшее представление об объеме используемой памяти. Это значение не изменяется, когда рабочий набор процесса обрезается. Более подробная информация содержится в этой статье Microsoft KB .

Вы можете вручную уменьшить рабочий набор вашего приложения с помощью вызова Win32 API SetProcessWorkingSetSize (GetCurrentProcess (), -1, -1).

Это то, что Windows будет делать в любом случае, когда системе не хватает памяти, но контроль, когда это происходит самостоятельно, позволяет обрезать рабочий набор приложения .NET до минимального размера для целей расследования.

Кстати, будьте очень осторожны при вызове GC.Collect () .

1 голос
/ 19 октября 2010

Идиоматическим способом борьбы с удалением объектов является интерфейс IDisposable .Это то, что позволяет вам использовать конструкцию using, чтобы гарантировать освобождение объектов.@ Джо прав;в большинстве случаев не следует вызывать сборщик мусора напрямую.

0 голосов
/ 20 октября 2010

нет, не утечка, это особенность. Не делайте GC.Collect, который противен. Я бы беспокоился только об утечке, если бы мой тестовый ящик падал из-за нехватки ресурсов, а не потому, что система использовала больше памяти, чем я ожидал. Сборщик мусора не работает, пока он действительно не работает. Я не думаю, что давление, которое вы оказываете на него, слишком велико для того, чтобы беспокоиться об этом.

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

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

0 голосов
/ 20 октября 2010

Я написал приложение .NET, где использование памяти растет со временем. Как тест, я установил его для загрузки 800 * 5K (средний) размер файла и выполнение XML преобразовать и использовать DTComcontroller для создать манифест, в течение 1 часа с интервал 15 минут. Во время период около 5 часов, использование памяти растет с 35 до 70 млн.

Это проблема? Если нет (то есть достаточно памяти), это может быть причиной. GC работает только тогда, когда память начинает дефицит. 70мб тоже очень мало вообще ИМХО.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...