Воскресенье, 19.05.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Нашли свой исходник?
Всего ответов: 94
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Разные » Обзор Delphi

Delphi 2007 (часть III - FastMM)

Введение

О чем речь

Ниже речь пойдет о FastMM - менеджере парамяти для Delphi for win32. Я поделюсь опытом использования данного продукта и покажу, какие можно получать выгоды от него.

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

Версии дельфи, для которых применим материал

Материал применим как для BDS2006, так и для Delphi2007 (возможно, что и для более ранных версий дельфи - я не проверял).

История FastMM

Насколько я понимаю, данный манагер памяти был алтернативным манагером до Delphi2005 включительно. Т.е. можно было скачать FastMM (он свободный, где брать - см. ниже) и включить его в свой проект, заменив штатный манагер. Начиная с BDS2006 FastMM уже включен в Delphi.

По сравнению с ранее существовавшим манагером FastMM обладает следующими достоинствами:

  1. Он быстрее.
  2. Он предоставляет сервисные функции для отладки и поиска утечек памяти.

Естественно FastMM включается не только в программы, создаваемый разработчиком, но и в саму IDE. Насколько я понимаю одной из причин резкого ускорения работы IDE при переходе от BDS2005 к BDS2006 был именно FastMM.

Проблемы

Проблема в том, что:

  1. В Delphi FastMM включается только как манагер памяти и как упрощенный поисковик утечек памяти.
  2. В Delphi в настоящий момент полностью отсутствует документация по поводу FastMM (есть соответствующий репорт - http://qc.codegear.com/wc/qcmain.aspx?d=27105, который уже открыт автором FastMM).

При этом никто не машает скачать полную версию FastMM и заменить ею "штатный" FastMM, который есть в Delphi, настроив заменяющий FastMM таким образом, чтобы получать максимальную выгоду от сервисных функций в процессе отладки.

Использование FastMM

Где брать

FastMM хостится на http://www.sourceforge.net. Вот точная ссылка на страницу проекта: http://sourceforge.net/projects/fastmm.

Далее идете по ссылке Download FastMM. и скачиваете версию 4.x. В настоящий момент последней версией является 4.78.

Как устанавливать

Устанавливать собственно и не надо ничего. Есть три файла, которые вам необходимы:

  1. FastMM4.pas
  2. FastMM4Messages.pas
  3. FastMM4Options.inc

Кладете их в каталог проекта (или в путях, прописанных в Library Path в настройках Delphi) и подключаете первым модулем проекта FastMM4.

В случае, если используются runtime пакеты, то FastMM4, естественно не нужно подключать в пакеты - только в главное приложение.

NB Как использовать FastMM для DLL я не знаю, ибо не разбирался. Но в файле FastMM4Options.inc есть очень много комментариев по поводу настройки FastMM. Скорее всего там можно выяснить этот вопрос.

Настройка FastMM

FastMM настраивается посредством опций условной компиляции, задаваемых в файле FastMM4Options.inc. Опции снабжены подробными комментариями. Я для своих задач сделал следующие изменения:

  1. Убрал комментарии для опций UseRuntimePackages, FullDebugMode, ClearLogFileOnStartup.
  2. Закомментировал опцию RequireDebuggerPresenceForLeakReporting.

NB При использовании FastMM с опцией FullDebugMode в каталоге проекта должна быть библиотека FastMM_FullDebugMode.dll, которая есть в поставке FastMM как в виде исходников, так и в виде скомпилированного файла. Подробнее см. каталог FastMM478.zip \FullDebugMode DLL.

Настройки проекта

При возникновении нештатных ситуаций FastMM показывает стек вызовов, приведший к ошибке. Для того, чтобы стек вызовов содержал имена функций и строк в исходном коде нужно в параметрах проекта (и runtime пакетов, если они используются) на закладке Linker в секции Map File выставить опцию Detailed.

Пример использования в целях получения стека вызовов, приведшего к утечке памяти

Цель примера показать, что в стеке вызовов, приведшего к утечке памяти будут методы TMyClass.Execute() и TMyClass.fProcess() с точным указанием номера строки исходного кода.

program Project1;
{$APPTYPE CONSOLE}
uses
 FastMM4,Classes,SysUtils;
type
 TMyClass = class
 public procedure Execute();
 strict private procedure fProcess();
 end;
procedure TMyClass.Execute();
begin
 fProcess();
end;
procedure TMyClass.fProcess();
var
 L: TList;
begin
 L := TList.Create();
end;
var
 MC: TMyClass;
begin
 MC := TMyClass.Create();
 try
 MC.Execute();
 finally
 MC.Free();
 end;
end.

Еси выполнить данную программу, то, во-первых, при завершении программы будет выведено сообщение о том, что были утечки, во-вторых, в каталоге программы будет создан файл Project1_MemoryManager_EventLog.txt, в котором будет представлена более подробная информация об утечке памяти.

В частности будет представлена следующая информация:

Stack trace of when this block was allocated (return addresses):
402DBE [system.pas][System][System.@GetMem][2648]
4036EF [system.pas][System][System.TObject.NewInstance][8824]
40399A [system.pas][System][System.@ClassCreate][9489]
403724 [system.pas][System][System.TObject.Create][8839]
403A08 [system.pas][System][System.@AfterConstruction][9537]
414935 [E:\temp\_Borland\FieldTest\01\Project1.dpr][Project1][Project1.TMyClass.fProcess][18]
41491B [E:\temp\_Borland\FieldTest\01\Project1.dpr][Project1][Project1.TMyClass.Execute][12]
4152FD
794589A5 [ProcessIdToSessionId]
The block is currently used for an object of class: TList

Видно, что здесь, во-первых, указан класс, объект которого "утек", во-вторых, указан стек вызовов, приведший к утечке.

Можете попробовать использовать указанный подход в своих оконных приложениях (я не стал этого здесь делать т.к. код бы получился очень большой). В этом случае будет выводится очень глубокий стек, начиная от VCL.

NB В какой-то момент может показаться ошибкой, что в стек иногда попадают лишние методы. Я не силен в архитектуре возбуждения исключений, поэтому могу только передать слова автора FastMM: "Я пользовался функцией построения стека, которая реализована в JEDI". От себя замечу, что именно этой функцией пользуется сама IDE в BDS2006 и Delphi2007. Наверное, стоит спокойно относится к лишним методам - лишь бы нужные методы не пропадали.

Пример использования в целях получения стека вызовов, приведшего к вызову метода удаленного объекта

Такой функционал - еще одна сервисная функция, предоставляемая FastMM.

В отладочном режиме (т.е. если включена опция условной компиляции FullDebugMode) FastMM при удалении объекта "портит" память, занимаемую ранее объектом, таким образом, что при следующей попытке вызывать виртуальный метод удаленного объекта FastMM возбуждает исключение.

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

Ниже представлен пример отслеживания момента повторного удаления объекта (деструктор тоже виртуальный метод).

program Project1;
{$APPTYPE CONSOLE}
uses
 FastMM4;
type
 TMyClass = class
 end;
var
 MC: TMyClass;
procedure Proc1;
begin
 MC := TMyClass.Create();
end;
procedure Proc2;
begin
 MC.Free();
end;
procedure Proc3;
begin
 MC.Free();
end;
begin
 Proc1;
 Proc2;
 Proc3;
end.

Запустите проект.

Во-первых, вы получите сообщение о том, что была попытка вызывать виртуальный метод удаленного объекта.

Во-вторых, в файле Project1_MemoryManager_EventLog.txt можно посмотреть:

  1. Стек вызовов при создании объекта.
  2. Стек вызовов при удалении объекта.
  3. Стек вызовов при попытке вызывать виртуальный метод объекта (в текущем примере это тот же деструктор).

ИМХО весьма полезно может быть.

Заключение

При анализе файла FastMM4Options.inc можно найти некоторые другие сервисные функции. Я с ними не разбирался, но, очевидно, что они также могут быть полезны при отладке.

Получить ссылку на материал

Категория: Обзор Delphi | Добавил: Барон (07.12.2011)
Просмотров: 2460 | Теги: FastMM | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
Delphi.NET [3]
Kylix Delphi for Linux [9]
Советы Дельферу [6]
Хитрости в Delphi [2]
Обзор Delphi [45]
Инсталлятор [11]
Пользовательский интерфейс [18]
Примеры Delphi [93]
Функции и процедуры [15]
Разные [31]
Королевство Delphi © 2010-2024
Яндекс цитирования