Стратегия или инструменты для поиска «негерметичных» проблем с использованием памяти в Delphi?

#delphi #memory-management #delphi-2006

#delphi #управление памятью #delphi-2006

Вопрос:

Одно старое приложение начало сильно потреблять память после обновления сервера. Использование памяти, похоже, увеличивается без ограничения, пока программа не зависнет.

Согласно FastMM4 и EurekaLog, утечки памяти нет (кроме 28 байт), поэтому я предполагаю, что вся память освобождается при завершении работы приложения.

Существуют ли какие-либо инструменты или стратегии, подходящие для отслеживания такого рода проблем с памятью?

Ответ №1:

С сентября 2012 года существует очень простой и удобный способ обнаружения утечек памяти такого типа «только во время выполнения».

FastMM4991 представил новый метод, LogMemoryManagerStateToFile :

Добавлен вызов LogMemoryManagerStateToFile. Этот вызов записывает в файл сводку состояния диспетчера памяти: общая выделенная память, служебные данные, эффективность и разбивка выделенной памяти по классам и строковым типам. Этот вызов может быть полезен для перехвата объектов, которые не обязательно протекают, но задерживаются дольше, чем должны.

Чтобы обнаружить утечку во время выполнения, вам понадобятся только следующие шаги

  1. добавьте вызов LogMemoryManagerStateToFile('memory.log', '') в место, где он будет вызываться с интервалами
  2. запустите приложение
  3. откройте файл журнала с помощью хвостовой программы (например, BareTail), которая будет автоматически обновляться при изменении содержимого файла
  4. посмотрите на первые строки файла, они будут содержать выделения памяти, которые занимают наибольший объем памяти
  5. если вы видите, что класс или тип памяти постоянно имеют растущее число экземпляров, это может быть причиной вашей утечки

Комментарии:

1. Не могли бы вы помочь прокомментировать, что следует делать, если файл подкачки продолжает расти после каждого выполнения, но memory.log не показывает постоянного роста?

Ответ №2:

  1. Растущее потребление памяти является проблемой приложения. Это не ошибка, которую могут обнаружить FastMM4 или EurekaLog. С их точки зрения — приложение просто правильно использует память.
  2. Используя AQTime, MemProof (трудно найти, D7 — последняя поддерживаемая версия (?)), SleuthQA (аналогично MemProof) или аналогичные профилировщики памяти, вы можете отслеживать использование памяти вне приложения в режиме реального времени.
  3. Используя 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 минут или реже

Уродливое решение, я знаю… но работает!!!