Стратегия или инструменты для поиска проблем с использованием памяти без утечек в Delphi?
Одно старое приложение стало много потреблять памяти после обновления сервера. Использование памяти, по-видимому, возрастает без ограничения до зависания программы.
Согласно FastMM4 и EurekaLog, утечки памяти нет (кроме 28 байт), поэтому я предполагаю, что вся память освобождается при завершении работы приложения.
Существуют ли какие-либо инструменты или стратегии, подходящие для отслеживания такого рода проблем с памятью?
4 ответа
- Растущее потребление памяти является проблемой приложения. Это не ошибка, которую может обнаружить FastMM4 или EurekaLog. С их точки зрения - приложение просто правильно использует память.
- Используя AQTime, MemProof (трудно найти, D7 - последняя поддерживаемая версия (?)), SleuthQA (аналогично MemProof) или аналогичные профилировщики памяти, вы можете отслеживать использование памяти вне приложения в режиме реального времени.
- Используя FastMM4, GetMemoryManagerState / GetMemoryManagerUsageSummary вы можете отслеживать использование памяти из приложения. Выведите эту информацию в файл трассировки и проанализируйте ее после запуска. Или создайте простую функцию обертывания для одной из вышеперечисленных процедур, которая вернет текущее использование памяти. И вызовите его из IDE Debugger Evalute / Modify, добавьте в Watches или вызовите OutputDebugString и посмотрите текущее использование памяти.
Обратите внимание, что если память используется какой-либо библиотекой DLL, вы можете не увидеть ее использование памяти с помощью (3). Используйте (2).
Анализируя использование памяти и задачи, выполняемые приложением, вы можете обнаружить, что приводит к повышенному использованию памяти.
С сентября 2012 года существует очень простой и удобный способ обнаружения утечек памяти этого типа только во время выполнения.
FastMM4991 представил новый метод, LogMemoryManagerStateToFile
:
Добавлен вызов LogMemoryManagerStateToFile. Этот вызов записывает сводку состояния диспетчера памяти в файл: общий объем выделенной памяти, накладные расходы, эффективность и распределение выделенной памяти по классу и типу строки. Этот вызов может быть полезен для обнаружения объектов, которые не обязательно просачиваются, но задерживаются дольше, чем должны.
Чтобы обнаружить утечку во время выполнения, вам нужны только эти шаги
- добавить вызов
LogMemoryManagerStateToFile('memory.log', '')
в месте, где это будет называться в промежутках - запустить приложение
- откройте файл журнала с помощью хвостовой программы (например, BareTail), которая будет автоматически обновляться при изменении содержимого файла
- просмотрите первые строки файла, они будут содержать выделения памяти, которые занимают наибольшее количество памяти
- если вы видите, что у класса или типа памяти постоянно растет число экземпляров, это может быть причиной вашей утечки
AQTime (коммерческий инструмент, который довольно дорогой) может сообщать об использовании вашей памяти вплоть до строки исходного кода, которая выделяет каждый объект. В случае сценариев очень большого использования памяти может потребоваться функция AQTime, которая может отображать количество объектов и размер (общий плюс размер отдельного экземпляра) для каждого объекта. AQTime отлично работал для меня, начиная с Delphi 7 и всех последующих версий, включая вашу версию (2006) и последние версии (XE и XE2).
По мере роста использования памяти программы AQTime можно использовать для получения "снимков" кучи времени выполнения, которую можно использовать для понимания использования памяти вашим приложением; Что создается и сколько существует каждого объекта. Даже когда нет утечек, понимание поведения приложения во время выполнения в терминах объектов, которые оно создает и управляет, очень важно, и AQTime - самый мощный инструмент, который я знаю для пользователей Delphi.
Если вы готовы перейти на Delphi XE/XE2, возможно, у вас уже есть облегченная версия AQTime, если так, проверьте ее. Если нет, я рекомендую вам попробовать их демо. Мне неизвестны какие-либо альтернативы с открытым или открытым исходным кодом, которые могут обеспечить такую же функциональность.
Меньшие функциональные возможности можно объединить вручную, написав множество сообщений трассировки или используя режим полной отладки FastMM. Если бы вы могли записать полный дамп использования памяти в очень большой файл, вы могли бы написать некоторые инструменты для анализа и создания сводки. Проблема, с которой я столкнулся в этом случае в FastMM, заключается в том, что вы будете утоплены в подробной информации, без возможности извлечь именно сводную информацию, которая поможет вам понять вашу ситуацию. Таким образом, вы можете попробовать написать свой собственный инструмент для подведения итогов использования памяти. В одном приложении, в котором использовался ряд компонентов, которые, как я знал, будет использовать много памяти, я записал в свое приложение диалоговое окно, в котором отображалось текущее использование памяти этими большими объектами памяти.
Вы когда-нибудь задумывались о утечке, которая вызывает IDE... она такая огромная!!!
В моем случае (2 ГБ ОЗУ) я делаю следующее... 1. Откройте IDE 2. Оставьте его свернутым на шесть часов 3. Посмотрите, как физическая память используется
Результат: в то время как IDE противостоит (помните, что я также делаю тест, свернув его до минимума), он получает все больше и больше оперативной памяти... до тех пор, пока не освободится оперативная память. Он получает все 2 ГБ ОЗУ + все пространство на жестком диске Pagefile (я настроил его на массу 4 ГБ). Менее чем за шесть часов (ничего не делая в IDE) он пытается использовать более 6 ГБ.
Это называется утечкой памяти в среде IDE... я не набираю буквы в IDE, ничего не компилирую, даже не открываю проекты... просто открываю IDE и минимизирую его... оставляю компьютер без работы что-нибудь на нем около шести часов и IDE потребляет 6 ГБ памяти.
Конечно, после этого IDE начинается с надоедливых сообщений SystemOutOfMemory... и я должен убить его... тогда все 6GB освобождаются!!!
Когда, черт возьми, это будет исправлено?
Пожалуйста, обратите внимание, что у меня есть все исправления, я также проверил без применения каждого исправления / исправления и т.д...
Лучшее, что я получил, - это отключение некоторых параметров в Инструментах, таких как тот, который подчеркивает плохой код и т. Д.... так почему, черт возьми, этот параметр имеет какое-то влияние... я ничего не печатаю в IDE (в тестах).... и если я отключил, утечка памяти значительно уменьшится...
Конечно, если я использую IDE (пишу код в открытом проекте), даже не скомпилировав / не запустив его... дело идет гораздо хуже... утечка памяти до 6 Гб может быть достигнута менее чем за час, иногда происходит после 15 минут копирования / вставки исходного кода.
Кажется, в скором времени решения не будет!!!
Итак, я получил следующее решение, которое отлично работает: -Закройте IDE и открывайте его каждые 15 минут или меньше.
Гадкое решение, я знаю... но работает!!!