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