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