Выслеживание EOutOfResources

Вопрос:

Существует ли простой способ получить список типов ресурсов, которые протекают в запущенном приложении? IOW путем соединения с приложением?

Я знаю, что memproof может сделать это, но это замедляется так, что приложение даже не продлится минуту. Большей части taskmanager нравится, может показать число, но не тип.

Это не проблема, что сама проверка является катастрофической (останавливает процесс приложения), так как я могу свериться с taskmgr, если я рядом (или по крайней мере я надеюсь),

Любое другое понимание на поиске утечки ресурсов (так не память) также одобрено.

Фон:

У меня есть Delphi 7/2006/2009 приложение (компиляции со всеми тремя) и приблизительно после некоторых неделя, оно начинает действовать забавное. Однако только на одном из мест это работает в нескольких других системах, которые это выполняет, пока питание не выходит.

Я попытался вставить некоторый код отладки для сужения проблемы. и узнанный, что исключением является EOutofResources на сохранении файла. (сохранение файла может произойти тысячи времен в день).

Я попытался продумать утечки памяти (с fastmm), но так как поток данных довольно высок (60MByte/s от гигабитного технического фотоаппарата), я могу только исключить "вползающие" утечки памяти с fastmm, не быстрые вспышки memoryleaks, которые исчерпывают память во время, это происходит. Если что-то идет не так, как надо, приложение заполняет память под половиной минуты.,

Основные подозреваемые являются дескрипторами файлов, которые так или иначе оставляют на некоторой ошибке и TMetafiles (которые передаются потоком в эти файлы). Младшими подозреваемыми является VST, popupmenu и tframes

Обновления:

Другая возможная подсказка: Это хорошо работало в течение двух лет с D7, и теперь проблемы с Турбо Проводником (который я использую для стабильных проектов, не преобразованных в D2009).

Paul-Jan: Так как это только происходит один раз в неделю (и это может произойти ночью), сбор информации является медленным. То, которое является, почему я задаю этот вопрос, должно объединить материал для того, когда я там в четверг. Короче говоря: нет я не знаю уверенных 100%. Я намереваюсь принести весь набор Systemtools, чтобы видеть, могу ли я найти что-то (потому что затем он будет работать в течение многих дней). Существует также шанс, что я вижу открытые файлы. (возможно, должен попытаться найти некоторый mingw lsof и запланировать его),

Но приложение видит очень мало действия GUI (это - приложение контроля машинного зрения), кроме экранного обновления +/-15/с, который является tbitmap stretchdraw + tmetafile, но я получаю эту ошибку при сохранении (TFileStream) на диск, дескрипторы, вероятно, действительно исчерпываются. Однако в том же потоке, TMetafile также savetostreamed, что-то, что более поздние приложения больше не имеют, и они могут работать с месяцев.

-------------------ОБНОВЛЕНИЕ

Я искал и искал и искал и сумел воспроизвести проблемы в пробирке два или три раза. Проблемы произошли, когда memusage был +/-256 МБ (системы имеют 2 ГБ), пользовательские объекты 200, gdi возражает 500, не один файл, более открытый, чем ожидалось).

Это не действительно исключительно. Я действительно замечаю, что пропускаю небольшие количества дескрипторов, вероятно, из-за перепорождения кадров (что-то в VCL, кажется, пропускает HPalette's), но я подозреваю, что базовой причиной является другая проблема. Я снова использую TMetafile и .clear это промежуток. Я думаю, очищая метафайл, не делает действительно (всегда?) изменяют размер ресурса, в конечном счете каждый метафайл во всем пуле tmetafile в максимальном размере, и с 20-40 + tmetafiles (который может быть несколькими 100 кс каждый), это поразит настольный предел "кучи".

Это - теория, но я попытаюсь проверить это путем установления настольного предела к 10 МБ в клиентах, но это будет за несколько недель до того, как у меня будет подтверждение, если это изменяет что-нибудь. Эта теория также подтверждает, почему эта машина является особенной (возможно, что эта машина естественно имеет немного большие метафайлы в среднем). Иногда освобождение и воссоздание tmetafile в пуле могли бы также помочь.

К счастью все эти проблемы (и tmetafile и повторно порождающий) были уже разработаны в более новых поколениях приложений.

Из-за особых обстоятельств (и то, что у меня есть очень ограниченные тестовые окна), это будет некоторое время, но я решил принять настольную "кучу" как пример на данный момент (хотя материал GDILeaks был также несколько полезен).

Другая вещь, что аудит показал использование типов GDI в потоке (хотя только сохраняя tmetafiles (которые не использовались или соединились иначе) к потокам.

-------------Обновление 2.

Увеличение настольного предела только, казалось, незначительно увеличило время, пока проблема не произошла.

К сожалению, я не смогу следовать этому далее, так как машины были обновлены к более новой версии платформы, которая не имеет проблемы.

Таким образом, я могу только заявить, что три базовых модификации шли от старого до новой платформы:

  • Я больше не изменяю экраны путем перепорождения кадров. Я теперь работаю с формами, которые я скрываю и показываю. Я изменил это, так как у меня также были очень редкие катастрофические отказы или исключения (который мог быть нажат далеко), из-за этого. Катастрофические отказы были всеми при работе GUI хотя, не спонтанно как основная проблема
  • Стандартная программа, где катастрофический отказ произошел, имела дело с TMetafile. TMetafile был разработан, и замена более простым собственным сделанным форматом. (в основном массивы с вершинами Opengl)
  • Рисования больше не происходило с tbitmap с strechdrawn наложения tmetafile по нему, но использованием OpenGL.

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

Обновленный ноябрь 2012 после некоторого частного почтового обсуждения: Ретроспективно, следующий шаг добавлял бы в противоречии с объектами метафайлов, и просто повторно инстанцирует их каждый x * приблизительно 1000 использования и видит, изменяет ли это что-нибудь. Если у Вас есть подобные проблемы, попытайтесь видеть, можно ли несколько регулярно уничтожать и повторно инициализировать долго живущие ресурсы, которые динамично выделяются.

11
задан Marco van de Voort 27 November 2013 в 11:39
поделиться

6 ответов

Если речь идет об утечках при работе с GDI, вы можете взглянуть на MSDN Magazine January 2003, в котором используется инструмент GDILeaks. Другими инструментами являются GDIObj или GDIView. См. также здесь .

Другим источником EOutOfResources может быть полная куча Desktop Heap. У меня была такая проблема на занятых терминальных серверах с большими экранами.

Если у вас утечка большого количества файловых дескрипторов, вы можете проверить Проводник процессов и посмотреть на открытые файловые дескрипторы вашего процесса, а также посмотреть что-нибудь необычное. Или используйте WinDbg с командой !htrace.

6
ответ дан 3 December 2019 в 04:32
поделиться

Большинство времен я видел eoutofresources , это была какая-то утечка ручки.

Вы попробовали что-то вроде Madexcept ?

- Jeroen

2
ответ дан 3 December 2019 в 04:32
поделиться

Также попробуйте проверить счетчик handle для приложения с помощью проводника Process Explorer из SysInternals. Утечка хэндла может быть очень опасной, и они медленно строятся во времени.

0
ответ дан 3 December 2019 в 04:32
поделиться

справиться с исключением.

Обычно исключение будет вручено структуру, которая содержит адрес, который вызвал исключение и другую информацию. Возможно, вам придется познакомиться с таблицей данных микроконтроллера или Руководство по RTOS.

-121--3223147-

«Я пытался поставить в какой-то код отладки, чтобы сузить проблему вниз. И выяснил, что исключением является eOutofresources на сохранении файла. (Сохранение файлов может произойти тысячи раз в день). "

Я стреляю в темноте здесь, но может быть, вы используете Windows API для (getTempfileName), создайте файл Temp, и вы выделяете некоторые файловые индексы или забывающие Чтобы закрыть ручку файла?

В любом случае, я согласен с тем, что с вашим предположением о том, что он является проблемой обработки файлов. Это, кажется, наиболее вероятным, учитывая ваши симптомы и диагностики.

2
ответ дан 3 December 2019 в 04:32
поделиться

Существует небольшая вероятность того, что ошибка вводит в заблуждение. VCL наивно сообщает EOutOfResources , если он не может получить DC для окна (см. TWinControl.GetDeviceContext в Controls.pas ).

Я говорю «наивно», потому что есть и другие причины, по которым GetDC () может возвращать нулевой дескриптор, а VCL должен сообщать об ошибке ОС, а не предполагать состояние нехватки ресурсов (есть версия для Windows проверка, необходимая для того, чтобы это было надежно возможным, но VCL может и должен это взять).

У меня была ситуация, когда я получал ошибку EOutOfResources в результате того, что дескриптор окна становился недействительным. Как только я обнаружил настоящую проблему, найти причину и устранить ее стало просто, но я потратил много, много часов, пытаясь найти несуществующую утечку ресурсов.

Если возможно, я бы исследовал трассировку стека, ведущую к этому исключению - если оно исходит из TWinControl.GetDeviceContext , то проблема может быть не в том, что вы думаете (конечно, невозможно сказать, что это может быть , но устранение невозможного - всегда первый шаг к поиску решения, каким бы невероятным оно ни было).

12
ответ дан 3 December 2019 в 04:32
поделиться

В настоящее время у меня возникла эта проблема в программном обеспечении, которое явно не пропускает никаких дескрипторов в моем собственном коде, поэтому, если есть утечки, они могут происходить в исходном коде компонента или самом исходном коде VCL. .

Счетчики дескрипторов, GDI и пользовательских объектов не увеличиваются, и при этом ничего не создается. Ответ Deltic показывает угловые случаи, когда сообщение является отвлекающим маневром, и Аллен предполагает, что даже запись файла может вызвать эту ошибку.

На данный момент лучшая стратегия, которую я нашел для их выслеживания, - это использовать либо трассировку стека JCL JCLDEBUG, либо функции сохранения отчета об исключениях в MadExcept для генерации контекстной информации и определения того, что на самом деле дает сбой.

Во-вторых, AQTime содержит множество инструментов, которые могут вам помочь, в том числе профилировщик ресурсов, который может поддерживать связи между тем, где находится код, создавший ресурсы, и тем, как он был вызван, а также подсчет общего количества дескрипторов. Он может захватывать результаты MID RUN и поэтому не ограничивается обнаружением неиспользованных ресурсов после выхода. Итак, запустите AQTime, сделайте захват результатов в середине выполнения, подождите несколько часов и снова захватите, и у вас должно быть два момента времени для сравнения счетчиков дескрипторов. На всякий случай это очевидная вещь.Но, как мудро указывает Deltics, этот класс исключения возникает в тех случаях, когда этого, вероятно, не должно было быть.

0
ответ дан 3 December 2019 в 04:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: