#delphi #memory-management #delphi-2006
#delphi #управление памятью #delphi-2006
Вопрос:
Одно старое приложение начало сильно потреблять память после обновления сервера. Использование памяти, похоже, увеличивается без ограничения, пока программа не зависнет.
Согласно FastMM4 и EurekaLog, утечки памяти нет (кроме 28 байт), поэтому я предполагаю, что вся память освобождается при завершении работы приложения.
Существуют ли какие-либо инструменты или стратегии, подходящие для отслеживания такого рода проблем с памятью?
Ответ №1:
С сентября 2012 года существует очень простой и удобный способ обнаружения утечек памяти такого типа «только во время выполнения».
FastMM4991 представил новый метод, LogMemoryManagerStateToFile
:
Добавлен вызов LogMemoryManagerStateToFile. Этот вызов записывает в файл сводку состояния диспетчера памяти: общая выделенная память, служебные данные, эффективность и разбивка выделенной памяти по классам и строковым типам. Этот вызов может быть полезен для перехвата объектов, которые не обязательно протекают, но задерживаются дольше, чем должны.
Чтобы обнаружить утечку во время выполнения, вам понадобятся только следующие шаги
- добавьте вызов
LogMemoryManagerStateToFile('memory.log', '')
в место, где он будет вызываться с интервалами - запустите приложение
- откройте файл журнала с помощью хвостовой программы (например, BareTail), которая будет автоматически обновляться при изменении содержимого файла
- посмотрите на первые строки файла, они будут содержать выделения памяти, которые занимают наибольший объем памяти
- если вы видите, что класс или тип памяти постоянно имеют растущее число экземпляров, это может быть причиной вашей утечки
Комментарии:
1. Не могли бы вы помочь прокомментировать, что следует делать, если файл подкачки продолжает расти после каждого выполнения, но
memory.log
не показывает постоянного роста?
Ответ №2:
- Растущее потребление памяти является проблемой приложения. Это не ошибка, которую могут обнаружить FastMM4 или EurekaLog. С их точки зрения — приложение просто правильно использует память.
- Используя AQTime, MemProof (трудно найти, D7 — последняя поддерживаемая версия (?)), SleuthQA (аналогично MemProof) или аналогичные профилировщики памяти, вы можете отслеживать использование памяти вне приложения в режиме реального времени.
- Используя FastMM4, GetMemoryManagerState / GetMemoryManagerUsageSummary, вы можете отслеживать использование памяти из приложения. Выведите эту информацию в файл трассировки и проанализируйте ее после запуска. Или создайте простую функцию переноса для одной из вышеупомянутых процедур, которая вернет текущее использование памяти. И вызовите его из IDE Debugger Evalute / Modify, добавьте в Watches или вызовите OutputDebugString и посмотрите текущее использование памяти.
Обратите внимание, если память загружается какой-либо DLL, вы можете не увидеть ее использование памяти с помощью (3). Используйте (2).
Анализируя использование памяти и задачи, выполняемые приложением, вы можете обнаружить, что приводит к увеличению использования памяти.
Комментарии:
1. MemProof (v.0.948, не уверен, что это был последний) все еще находится на Торри: torry.net/authorsmore.php?id=1229
2. Проблема в том, что это приложение серверного типа, поэтому определить одно действие очень сложно.
3. @Harriv Решение GetMemoryManagerUsageSummary — это то, что вам нужно. Я использовал это в многопоточном сервисе, и это, по крайней мере, указывает на размер элементов памяти, которые выходят из-под контроля.
4. Для многопоточного приложения возможность отслеживания является обязательной.
5. @mj2008: Не могли бы вы вкратце объяснить, как вы использовали GetMemoryManagerUsageSummary?
Ответ №3:
AQTime (коммерческий инструмент, который является довольно дорогим) может сообщать об использовании вашей памяти, вплоть до строки исходного кода, которая выделила каждый объект. В случае очень больших сценариев использования памяти вам может понадобиться функциональность AQTime, которая может отображать количество объектов и размер (общий плюс размер отдельного экземпляра) для каждого объекта. AQTime отлично работал для меня, начиная с Delphi 7 и всех более поздних версий, включая вашу версию (2006) и последние версии (XE и XE2).
По мере роста использования памяти программой AQTime можно использовать для получения «снимков» кучи времени выполнения, которые вы можете использовать для понимания использования памяти вашим приложением; Что создается и сколько существует каждого объекта. Даже когда утечек нет, понимание поведения вашего приложения во время выполнения с точки зрения объектов, которые оно создает и которыми управляет, очень важно, и AQTime — самый мощный инструмент, который я знаю для пользователей Delphi.
Если вы хотите перейти на Delphi XE / XE2, возможно, у вас уже есть включенная облегченная версия AQTime, если да, проверьте ее. Если нет, я рекомендую вам попробовать их демонстрацию. Я не знаю о каких-либо бесплатных или открытых источниках, которые могут обеспечить ту же функциональность.
Меньшую функциональность можно было бы собрать вручную, написав множество сообщений трассировки или используя FastMM в режиме полной отладки. Если бы вы могли записать полный дамп вашего использования памяти в очень большой файл, вы могли бы написать некоторые инструменты для анализа и создать сводку. Проблема, с которой я сталкиваюсь с FastMM в этом случае, заключается в том, что вы утонете в подробной информации, без возможности извлечь точную сводную информацию, которая поможет вам понять вашу ситуацию. Итак, вы можете попробовать написать свой собственный инструмент для обобщения использования памяти. В одном из моих приложений, в котором использовался ряд компонентов, которые, как я знал, будут использовать много памяти, я написал диалоговое окно в свое приложение, которое показывало текущее использование памяти этими большими объектами-блоками данных.
Комментарии:
1. Просто обратите внимание: Denomo не компилируется под D2006, а когда исправлено, что-то повреждает, и приложение становится непригодным для использования.
Ответ №4:
Вы когда-нибудь задумывались об утечке, которая вызывает IDE … она такая огромная!!!
В моем случае (2 ГБ ОЗУ) я делаю следующее … 1. Откройте IDE 2. Оставьте его свернутым почти на шесть часов 3. Посмотрите, как используется физическая память
Результат: в то время как IDE включена (помните, что я также провожу тест, сведя его к минимуму), он получает все больше и больше оперативной памяти … пока не останется свободной. Он получает все 2 ГБ оперативной памяти все место на жестком диске с файлами подкачки (я настроил его на mas 4 ГБ) Менее чем за шесть часов (ничего не делая в IDE), он пытается использовать более 6 ГБ.
Это называется утечкой памяти, вызванной IDE … я не набираю ни одной буквы в IDE, ничего не компилирую, даже не открываю ни один проект… просто откройте IDE и сверните его … оставьте компьютер, ничего не делая на нем около шести часов, а IDE потребляет 6 ГБ памяти.
Конечно, после этого IDE запускается с раздражающими сообщениями SystemOutOfMemory… и я должен убить его … тогда все эти 6 ГБ будут освобождены!!!
Когда, черт возьми, это будет исправлено?
Пожалуйста, обратите внимание, что у меня применены все исправления, я также тестировал без применения каждого исправления / исправления и т. Д…
Лучшее, что я получил, это отключить некоторые опции в инструментах, например, тот, который подчеркивает плохой код и т. Д… так почему, черт возьми, этот параметр имеет какое-либо влияние… я ничего не печатаю в IDE (в тестах)… и если я отключу его, утечка памяти значительно уменьшится…
Конечно, если я использую IDE (пишу код в открытом проекте), даже не компилируя / не запуская его … дело обстоит гораздо хуже … утечка памяти до 6 ГБ может быть достигнута менее чем за час, иногда происходит после 15 минут копирования / вставки исходного кода.
Кажется, в ближайшее время решения не будет!!!
Итак, я получил следующее решение, которое работает идеально: -Закройте IDE и открывайте его каждые 15 минут или реже
Уродливое решение, я знаю… но работает!!!