FastMM и динамически загружаемые библиотеки DLL - PullRequest
2 голосов
/ 07 июня 2010

У меня есть хост-приложение, которое загружает дюжину библиотек при запуске.Я хочу переключиться с диспетчера памяти по умолчанию в Delphi 7s на полную версию FastMM4 для лучшего отчета об утечке памяти.

Должен ли я включить FastMM4 в раздел users как основного приложения, так и библиотек?А как насчет общих пакетов времени выполнения?


Некоторая дополнительная информация:

  • У нас есть один exe и> 20 dll.Все делятся одним пакетом времени выполнения.
  • Сегодня мы не используем sharemem.Не то чтобы я знал об этом.ShareMem не входит ни в одну из версий exe или dll, которые я быстро просмотрел на сегодня.

Дополнительные вопросы:

  • Могу ли я использовать те же опции в fastmemsinc файл во всех проектах, или exe и dll нужны разные настройки?

Ответы [ 6 ]

8 голосов
/ 07 июня 2010

Выдержка из FastMM4options.inc файла.

Для меня это означает, что если все ваши пакеты, dll и исполняемые файлы скомпилированы с ShareMM, должна быть возможность заменить менеджер памяти Delphi 7s по умолчанию.

{----------------------- Менеджер памяти разделение Опции ------------------------}

{Разрешить совместное использование менеджера памяти между основным приложением и DLL которые также были скомпилированы с FastMM. Это позволяет передавать динамические массивы и длинные строки в функции DLL при условии, что оба скомпилированы для использования FastMM. Обмен будет работать только если библиотека, которая должна делиться менеджер памяти был скомпилирован с Параметр «AttemptToUseSharedMM» установлен. Обратите внимание, что если основное приложение однопоточный и DLL многопоточный, что вы должны установить переменная IsMultiThread в основной приложение к истине, или оно потерпит крах когда возникает конфликт потоков. Заметка что статически связанные файлы DLL инициализируется перед основным приложение, поэтому основное приложение вполне может в конечном итоге разделить статически загружен менеджер памяти DLL, а не наоборот. }

{. $ Define ShareMM}

{Разрешить совместное использование менеджера памяти DLL с другими DLL (или основной приложение, если это статически загружен DLL), которые также были скомпилированы с FastMM. Установите эту опцию с заботиться о динамически загружаемых DLL, потому что если DLL, которая разделяет его ММ выгружается и любая другая DLL все еще разделяет ММ, то приложение вылетит. Эта настройка актуально только для библиотек DLL и требует, чтобы ShareMM также был установлен в иметь какой-либо эффект. Делиться будет только работать, если библиотека, которая должна поделиться диспетчером памяти было составлено с Параметр «AttemptToUseSharedMM» установлен. Обратите внимание, что если DLL статически связаны, то они будут инициализированы перед основным применением и тогда DLL на самом деле поделится своим ММ с основным приложением. это опция не действует, если ShareMM не также установлен.}

{. $ Define ShareMMIfLibrary}

{Определите это, чтобы попытаться поделиться ММ основного приложения или другой загруженные библиотеки DLL в том же процессе, что были скомпилированы с набором ShareMM. когда разделять диспетчер памяти, память утечек, вызванных разделителем, не будет освобождается автоматически Принять в учетная запись, что статически связанные библиотеки DLL инициализируются перед основным приложение, поэтому установите общий доступ варианты соответственно.}

{. $ Define AttemptToUseSharedMM}

{Определите это, чтобы включить в обратном направлении совместимость для менеджера памяти механизм совместного использования, используемый Delphi 2006 и 2007, а также более старый FastMM версии.}

{$ DEFINE EnableBackwardCompatibleMMSharing}

3 голосов
/ 07 июня 2010

То, что вы ищете, называется SimpleShareMem. Он включен в пакет FastMM. Убедитесь, что ваше приложение и ваши библиотеки DLL используют его, а FastMM4 в начале их использует предложение . Это гарантирует, что все они используют одну и ту же кучу вместо использования отдельных.

Конечно, общая память необходима, только если вы собираетесь передавать динамическую память между приложением и библиотеками, такими как строки или объекты. Если нет, то вам не нужен SimpleShareMem, но я все равно рекомендую переключить библиотеки на FastMM в качестве диспетчера памяти для повышения производительности и стабильности.

1 голос
/ 09 июня 2010

с тех пор, как «Все используют один и тот же пакет времени выполнения». Я бы порекомендовал метод, который я использую. Просто добавьте FastMM4 в общий пакет времени выполнения (разумеется, вам нужно будет поставить FastMM4 в «использование» декларации в каждой библиотеке и хост-приложении в любом случае). Этот способ имеет некоторые преимущества, такие как:

  • простой метод для включения / выключения FullDebugMode [и других вариантов, конечно]. Перекомпиляция проекта не требуется, перекомпиляции только общего пакета достаточно для переключения FullDebugMode во всем приложении (включая DLL), поскольку FastMM создается только один раз.

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

  • нет проблем с диспетчером памяти при выгрузке плагинов. У меня были некоторые проблемы с удалением FastMM после выгрузки первой библиотеки плагинов, что приводило к множеству ошибок при завершении работы приложения.

  • нет проблем с отслеживанием - в случае утечки памяти или других проблем с памятью вам будет предоставлен действительный стек вызовов, даже если ошибка возникла в коде DLL.

Вот (нестандартные) опции, которые я использую в своем FastMM4Options.inc, чтобы все работало, как описано выше.

{$ define NeverUninstall} {$ define UseRuntimePackages} {. $ define ShareMM}

ну, я думаю, что остальное осталось без изменений, но если что-то не так, вот полный файл: http://pastebin.4programmers.net/693

0 голосов
/ 07 июня 2010

У Ypu есть два варианта: продолжать использовать модуль ShareMem и замену BorldMM.dll, которую вы найдете в дистрибутиве FastMM, или изменить и исполняемый файл и библиотеки DLL, чтобы включить менеджер памяти FastMM, поместив Блок как первый. Вам также следует адаптировать некоторые из $ DEFINE, которые вы найдете в FastMM4Options.inc, к вашим потребностям, они там хорошо объяснены. Пакеты времени выполнения AFAIK используют установленный менеджер памяти.

0 голосов
/ 07 июня 2010

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

Если ваше приложение скомпилировано без пакетов времени выполнения, то у каждой библиотеки есть свой собственный менеджер памяти. По умолчанию все они используют свои менеджеры памяти по умолчанию, и, если я не ошибаюсь, это общий MM, то есть вы можете передавать строки, например, в и из dll. Если вы хотите заменить MM по умолчанию другим совместным, вам нужно будет включить новый диспетчер памяти в качестве первого модуля в списке использований в КАЖДОЙ dll или exe, с которой вы хотите работать вместе.

Разница в том, что при выполнении совместного использования пакетов происходит на уровне пакета. Даже не разделяя ММ будет делиться. Без пакетов времени выполнения каждая DLL использует отдельный MM, и только когда эти отдельные менеджеры памяти взаимодействуют, вы получаете общий доступ.

Мое мнение таково, что, если ваше приложение не взаимодействует с dll очень тесно (читай: имеет формы и компоненты в dll), лучший подход - не полагаться на менеджер общей памяти вообще, а на правильное управление памятью, отслеживание кто что создает и удаляет объекты в той же библиотеке, где вы их создали. Это не трудно. Просто возвращайте интерфейсы вместо объектов, возвращайте короткие строки (фиксированной длины) или копируйте данные в предоставленный буфер вместо возвращаемых строк и так далее. Не возвращайте вещи, которые будут освобождены звонящим, не принимайте вещи, которые звонящий должен будет освободить, и вы будете в основном в безопасности. Это не только решает все возможные проблемы с менеджером памяти, но и позволяет писать dll на любом языке.

0 голосов
/ 07 июня 2010

Afaik есть sharemm, версия fastmm для совместного использования через библиотеки DLL.

...