Вопрос:
Есть ли простой способ получить список типов ресурсов, которые протекают в работающем приложении? IOW, подключившись к приложению?
Я знаю, что memproof может это сделать, но он так сильно тормозит, что приложение не продержится и минуты. Большинство лайков диспетчера задач могут отображать число, но не тип.
Это не проблема, что сама проверка является катастрофической (останавливает процесс приложения), так как я могу проверить с помощью taskmgr, приближаюсь ли я (или, по крайней мере, я надеюсь)
Также приветствуются любые другие идеи по поиску утечек ресурсов (но не памяти).
Задний план:
У меня есть приложение Delphi 7/2006/2009 (компилируется со всеми тремя), и примерно через несколько недель оно начинает вести себя забавно. Однако только в одном месте он работает, в нескольких других системах он работает до отключения электроэнергии.
Я попытался добавить отладочный код, чтобы сузить проблему. и обнаружил, что исключение составляет EOutofResources при сохранении файла. (сохранение файла может происходить тысячи раз в день).
Я пытался объяснить утечки памяти (с помощью fastmm), но поскольку поток данных довольно велик (60 МБ / с с гигабитных промышленных камер), я могу исключить только "ползучие" утечки памяти с помощью fastmm, а не быстрые вспышки утечек памяти, которые истощают воспоминания о времени, когда это происходит. Если что-то пойдет не так, приложение заполнит память менее чем за полминуты.,
Основными подозреваемыми являются дескрипторы файлов, которые каким-то образом остаются при какой-либо ошибке, и TMetafiles (которые передаются в эти файлы). Незначительные подозреваемые - VST, всплывающие меню и фреймы.
Обновления:
Другой возможный совет: два года он работал с D7 нормально, а теперь проблемы с Turbo Explorer (который я использую для стабильных проектов, не преобразованных в D2009).
Пол-Ян: Поскольку это происходит только раз в неделю (а это может происходить ночью), сбор информации идет медленно. Вот почему я задаю этот вопрос: нужно комбинировать вещи, когда я буду там в четверг. Короче: нет, я не уверен на 100%. Я собираюсь принести всю коллекцию Systemtools, чтобы посмотреть, смогу ли я что-нибудь найти (потому что тогда она будет работать в течение нескольких дней). Также есть вероятность, что я вижу открытые файлы. (может быть, стоит попытаться найти немного mingw lsof и запланировать его)
Но приложение видит очень мало действий графического интерфейса (это приложение для проверки машинного зрения), за исключением обновления экрана +/- 15 / с, которое является tbitmap stretchdraw + tmetafile, но я получаю эту ошибку при сохранении на диск (TFileStream), дескрипторы, вероятно, < я> действительно измучен. Однако в том же потоке TMetafile также сохраняется в потоке, чего больше нет в более поздних приложениях, и они могут работать в течение нескольких месяцев.
------------------- ОБНОВИТЬ
Я искал, искал и искал, и мне удалось воспроизвести проблемы in-vitro два или три раза. Проблемы возникали, когда память была +/- 256 МБ (в системе 2 ГБ), пользовательские объекты 200, объекты gdi 500, ни один файл не был открыт больше, чем ожидалось).
На самом деле это не исключение. Я действительно замечаю, что у меня утечка небольшого количества дескрипторов, вероятно, из-за репарентинга фреймов (что-то в VCL, похоже, пропускает HPalette), но я подозреваю, что основная причина - другая проблема. Я повторно использую TMetafile и очищаю его между собой. Я думаю, что очистка метафайла на самом деле (всегда?) Не изменяет размер ресурса, в конечном итоге каждый метафайл во всем пуле tmetafile имеет максимальный размер, а с 20-40 + tmetafile (которые могут быть несколько 100k каждый) это попадет на рабочий стол ограничение кучи.
Это теория, но я попытаюсь проверить это, установив ограничение рабочего стола на 10 МБ у клиентов, но пройдет несколько недель, прежде чем я получу подтверждение, изменится ли это что-нибудь. Эта теория также подтверждает, почему эта машина является особенной (возможно, что у этой машины в среднем немного большие метафайлы). Иногда также может помочь освобождение и воссоздание t-метафайла в пуле.
К счастью, все эти проблемы (как tmetafile, так и повторное родительство) уже были разработаны в новых поколениях приложений.
Из-за особых обстоятельств (и того факта, что у меня очень ограниченные тестовые окна) это займет некоторое время, но я решил пока взять кучу рабочего стола в качестве примера (хотя материал GDILeaks также был несколько полезен).
Другое дело, что аудит выявил использование GDI-типов в потоке (правда, с сохранением только tmetafiles (которые не использовались или не подключались иным образом) в потоках.
------------- Обновление 2.
Увеличение лимита рабочего стола лишь незначительно увеличило время до возникновения проблемы.
К сожалению, я не смогу следить за этим дальше, поскольку машины были обновлены до более новой версии фреймворка, в которой нет проблемы.
Подводя итог, я могу только указать, какие три основные модификации произошли от старого к новому фреймворку:
- Я больше не меняю экраны, переделывая фреймы. Теперь я работаю с формами, которые скрываю и показываю. Я изменил это, так как из-за этого у меня также были очень редкие сбои или исключения (которые можно было удалить). Сбои происходили во время работы с графическим интерфейсом, а не спонтанно, как основная проблема.
- Процедура, в которой произошел сбой, связана с TMetafile. TMetafile был разработан и заменен более простым собственным форматом. (в основном массивы с вершинами Opengl)
- Рисование больше не происходило с tbitmap с наложенным поверх него tmetafile оверлеем, а с использованием OpenGL.
Конечно, это может быть что-то еще, что было изменено при переписывании вышеуказанных частей, исправив очень неприятную ошибку в деталях. Это должно быть очень плохо, так как я проанализировал вышеупомянутую систему, насколько мог.
Обновлено ноя 2012 после обсуждения в частной переписке: в ретроспективе следующим шагом было бы добавление счетчика к объектам метафайлов и их простое повторное создание каждые x * 1000 использований или около того, и посмотреть, изменится ли это. что-либо. Если у вас есть подобные проблемы, попробуйте посмотреть, можете ли вы как-то регулярно уничтожать и повторно инициализировать долгоживущие ресурсы, которые распределяются динамически.