Как проанализировать чрезмерное потребление памяти (PageFileUsage) в приложении Delphi? - PullRequest
4 голосов
/ 15 марта 2012

Это продолжение этого вопроса: Чем можно объяснить разницу в использовании памяти, сообщаемую FastMM или GetProcessMemoryInfo?

Мое приложение Delphi XE использует очень большой объем памяти, что иногда приводит к исключению нехватки памяти. Я пытаюсь понять, почему и чем вызвано такое использование памяти, и хотя FastMM сообщает о низком использовании памяти, при запросе TProcessMemoryCounters.PageFileUsage я четко вижу, что приложением используется много памяти.

Я хотел бы понять, что вызывает эту проблему, и хотел бы посоветовать, как ее решить:

  • Есть ли способ узнать, что содержится в этой памяти и где она была выделена?
  • Существует ли какой-либо инструмент для отслеживания использования памяти по строкам / процедурам в приложении Delphi?
  • Какой-нибудь общий совет о том, как справиться с такой проблемой?

РЕДАКТИРОВАТЬ 1 : Вот два снимка экрана FastMMUsageTracker, указывающих, что память была выделена системой.

  • Перед началом процесса:

Before process starts

  • После завершения процесса:

After process ends

Условные обозначения: светло-красный выделен FastMM, а темно-серый выделен системой.

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

EDIT 2 : Я бы предпочел не использовать полную версию AQTime по нескольким причинам:

  • Я использую несколько виртуальных машин для разработки, и их система лицензирования является PITA (я уже зарегистрированный пользователь TestComplete)
  • LITE версия не предоставляет достаточно информации, и я не буду тратить деньги, не убедившись, что полная версия даст мне ценную информацию

Есть еще предложения?

Ответы [ 2 ]

4 голосов
/ 16 марта 2012

Другая проблема может быть фрагментация кучи. Это означает, что у вас достаточно свободной памяти, но все свободные блоки слишком малы. Вы можете увидеть это визуально, используя исходную версию FastMM и использовать FastMMUsageTracker.pas, как предложено здесь .

4 голосов
/ 15 марта 2012

Вам нужен профилировщик, но даже этого будет недостаточно во многих местах и ​​случаях. Кроме того, в вашем случае вам понадобится полнофункциональный AQTime, а не облегченная версия, которая поставляется с Delphi XE и XE2. (AQTIME очень дорогой и раздражающе блокируемый узлом, так что не думайте, что я - дурак для программного обеспечения SmartBear.)

Дело в том, что люди часто ошибочно принимают AQTime Allocation Profiler за способ обнаружения утечек. Он также может сказать вам, куда уходит ваша память, по крайней мере, в рамках инструмента. Работая и занимая много памяти, я нажимаю «Выполнить» -> «Получить результаты».

Вот одно из моих приложений, работающих в AQTime с профилем Allocation Profiler, показывающим, какой именно класс выделяет, сколько экземпляров в куче и сколько памяти они используют. Поскольку вы сообщаете о низком уровне использования кучи Delphi с помощью FastMM, это говорит о том, что большая часть возможностей AQTime для анализа по имени класса delphi также будет бесполезна для вас. Однако, используя события и триггеры AQTime, вы сможете определить, какие области вашего приложения вызывают «затраты на использование памяти», а когда это происходит, каковы затраты. Инструментарий AQTime в реальном времени может быть достаточным, чтобы помочь вам сузить причину, даже если он может не определить, какой вызов функции вызывает наибольшее использование памяти автоматически.

enter image description here enter image description here enter image description here Имена столбцов включают «Имя объекта», которое включает в себя такие вещи: * Все классы Delphi, их количество экземпляров и использование кучи. * Блоки виртуальной памяти, выделенные через вызовы Win32.

Он может определять выделение библиотек Delphi и C / C ++ в куче и может видеть определенные выделения памяти уровня Windows-API.

Обратите внимание на количество объектов в реальном времени, объем памяти из используемой кучи.

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

Один FastMM не может даже обнаружить не-delphi-распределение или выделение из кучи, которая не управляется FastMM. AQTime не ограничивается этим.

...