Менеджер накопления памяти

Как я могу использовать менеджер памяти в Delphi? Ищу альтернативу FastMM, бесперспективной для серьезных многопоточных серверных приложений. Я посмотрел на ScaleMM2, но он нестабилен в 64-битной версии.

Как я могу статически связать файл Hoard Memory Manager. Поскольку он поставляется с файлом OBJ.


person user3863403    schedule 25.07.2014    source источник


Ответы (3)


Как уже упоминал Дэвид, вам нужна версия .dll. Если вы не можете собрать его самостоятельно, вы можете найти готовые версии. Быстрый поиск показал только более старую версию.

Андре Мюше изменил FastCode MM Challenge, добавив Hoard в 2011 году. Если вы просматриваете исходный код, вы увидите примеры его использования. , включая еще одну предварительно скомпилированную копию winhoard.dll. Однако производительность и использование памяти в этих тестах было не очень хорошим.

person Bruce McGee    schedule 25.07.2014
comment
В противовес этому, в моем приложении, когда я тестировал Hoard, было определенное улучшение FastMM. Поэтому мне кажется, что разные приложения могут лучше или хуже подходить к конкретным менеджерам памяти. На самом деле этого и следовало ожидать. Для кода с очень высокой производительностью нелишним будет разработать специальные распределители, предназначенные для конкретной среды, которую они обслуживают. - person David Heffernan; 25.07.2014
comment
И FWIW, в исходном коде, на который вы ссылаетесь, есть этот блок: http://scalemm.googlecode.com/svn/trunk/Challenge/HoardMM.pas, в котором есть это объявление msvcrtDLL = 'libhoard.dll', которое заставляет меня смеяться. На самом деле этот код и этот (scalemm.googlecode.com/svn/trunk /Challenge/msvcrtMM.pas) вроде бы написаны мной! - person David Heffernan; 25.07.2014
comment
Да, все в порядке. В любом случае написать его не так уж и сложно. Я полагаю, что разместил его в стеке или в одном чьем-то блоге. Обновление: вот оно: stackoverflow.com/questions/6072269/ - person David Heffernan; 25.07.2014
comment
Я не буду утверждать, что все тесты FastCode представляют собой реальные сценарии. Если существует лучший общий контрольный показатель, он может быть более репрезентативным. - person Bruce McGee; 25.07.2014
comment
Подозреваю, что добиться этого очень сложно. Потому что разные приложения могут иметь совершенно разные шаблоны использования памяти, и я считаю, что невозможно оптимизировать все разумные шаблоны использования. Я думаю, что любой, кто хочет улучшить производительность своего приложения, лучше всего попробует доступные параметры в настройках своего приложения. Бенчмарк реального мира. И +1 кстати. - person David Heffernan; 25.07.2014

Вы не можете реально надеяться статически связать Hoard, потому что он реализован на C++ и поэтому нуждается в среде выполнения C++. Вы не можете рассчитывать на то, что в вашу программу Delphi будет встроена среда выполнения C++.

Поэтому вам нужно создать диспетчер памяти Hoard в DLL, например, с помощью Visual Studio. Эта DLL должна экспортировать malloc, free и realloc. Сделайте это с файлом .def. Затем вы создаете простой модуль Delphi, который связывается с DLL и устанавливает диспетчер памяти на основе этих импортированных функций. Используйте мой ответ на другой вопрос, чтобы помочь вам. Как всегда, сделайте блок управления памятью первым в списке использования вашего файла .dpr.

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

FWIW, я использую malloc из среды выполнения системы C в msvcrt.dll, которая масштабируется лучше, чем FastMM.

person David Heffernan    schedule 25.07.2014
comment
Это сильно зависит от приложения. IIRC, для моего приложения hoard был немного лучше (незначительно), чем msvcrt, а FastMM значительно хуже. Но современный msvcrt (Vista+) лучше старых версий (XP), IIRC. Но другие тесты приходят к другим выводам. В моем случае лучшим изменением, которое я когда-либо делал, было прекращение использования кучи везде, где это возможно. - person David Heffernan; 25.07.2014
comment
Возможно, это могло быть. Это может потребовать небольшого усилия. Вполне могут быть некоторые шаги инициализации, которые потребуют специальной обработки. И компилятор Borland, вероятно, хуже, чем компиляторы MS или Intel с точки зрения производительности. Поэтому статическая ссылка может быть немного сложной. И есть еще проблема с GPL. - person David Heffernan; 25.07.2014
comment
Ну, Hoard написан на C, так что C++ здесь неуместен. Да, вы можете попытаться связать созданные MSVC файлы .obj. Это не самая легкая задача в мире. Особенно для сложной части кода. Могут потребоваться навыки ниндзя. - person David Heffernan; 25.07.2014
comment
На самом деле я был неправ. Клад реализован на C++. Так что вам нужно придерживаться DLL. - person David Heffernan; 25.07.2014
comment
Мы постоянно используем код C++ из кода C. Это просто. Все, что нужно, это C-совместимый интерфейс. Частично это означает, что функции имеют связь с C, что вы делаете, используя extern "C". Это имеет побочный эффект, заключающийся в том, что не используется изменение имени C++. Например, см. конец libhoard.cpp< /и>. Связать его с Delphi не обязательно так просто, потому что вам также придется предоставить ссылки на стандартные библиотеки C и C++. Компиляторы C и C++ делают это автоматически, а Delphi — нет. - person Rob Kennedy; 25.07.2014
comment
Но, возможно, вы можете скомпилировать его для статической компоновки. В этом случае вы можете продолжать использовать код Дэвида в качестве отправной точки, но вместо реализации функций Delphi с точки зрения malloc и free из MSVCRT, вы бы реализовали их, используя xxmalloc и xxfree из объектных файлов Hoard. Обратите внимание, что xxrealloc реализован в другом исходном файле, winwrapper.cpp вместо libhoard.cpp. Вы можете использовать этот xxrealloc или перевести его реализацию в Delphi. - person Rob Kennedy; 26.07.2014
comment
Насколько я понял из кода, DLL на самом деле не экспортирует эти функции. (Возможно, так оно и было тогда, когда FastCode тестировал его, но не сейчас?) Скорее, он ожидает, что вы уже используете DLL из MSVC, поэтому вместо этого он просто исправляет функции из этих DLL. Используйте код Дэвида для функций памяти MSVCRT, а затем также загрузите DLL-библиотеку Hoard. Для этого и предназначен uselibhoard.cpp. - person Rob Kennedy; 26.07.2014
comment
Я не знаю. Попробуйте и отчитайтесь. Есть только так много предположений, которые я могу сделать. Вы тот, у кого есть компилятор и проблема, которую нужно решить. - person Rob Kennedy; 26.07.2014
comment
@user Вам просто нужно сделать то, что вам уже сказали. Никому не нравится, когда ему говорят, что это не работает. Там нет подробностей. Встроить Hoard в DLL. Экспортируйте malloc, free и realloc. Для этого используйте файл .def. Используйте модуль msvcrtMM из моего другого ответа, но измените имя DLL (и имя модуля). Вот и все. Сборка DLL и экспорт через файл def хорошо задокументированы в MSDN. - person David Heffernan; 27.07.2014

Поскольку все НЕ ПРОШЛИ предоставить подробное решение. Вот решение, которое действительно работает.

1: Откройте libhoard.cpp 2: Добавьте в код следующие строки.

extern "C"{

__declspec(dllexport) void* scalable_malloc (size_t size)
{
    return malloc(size);
}

__declspec(dllexport) void* scalable_realloc (void* ptr, size_t size)
{
    return realloc(ptr, size);
}

__declspec(dllexport) void scalable_free (void* ptr)
{
    free(ptr);
}

}

3: Скомпилируйте с nmake windows

4: Используйте это

unit hoard_mm;

interface

implementation

type
  size_t = Cardinal;

const
  hoardDLL = 'libhoard.dll';

function scalable_malloc(Size: size_t): Pointer; cdecl; external hoardDLL;
function scalable_realloc(P: Pointer; Size: size_t): Pointer; cdecl; external hoardDLL;
procedure scalable_free(P: Pointer); cdecl; external hoardDLL;

function GetMem(Size: NativeInt): Pointer; inline;
begin
  Result := scalable_malloc(size);
end;

function FreeMem(P: Pointer): Integer; inline;
begin
  scalable_free(P);
  Result := 0;
end;

function ReallocMem(P: Pointer; Size: NativeInt): Pointer; inline;
begin
  Result := scalable_realloc(P, Size);
end;

function AllocMem(Size: NativeInt): Pointer; inline;
begin
  Result := GetMem(Size);
  if Assigned(Result) then
  FillChar(Result^, Size, 0);
end;

function RegisterUnregisterExpectedMemoryLeak(P: Pointer): Boolean; inline;
begin
  Result := False;
end;

const
  MemoryManager: TMemoryManagerEx = (
    GetMem: GetMem;
    FreeMem: FreeMem;
    ReallocMem: ReallocMem;
    AllocMem: AllocMem;
    RegisterExpectedMemoryLeak: RegisterUnregisterExpectedMemoryLeak;
    UnregisterExpectedMemoryLeak: RegisterUnregisterExpectedMemoryLeak
  );

initialization
  SetMemoryManager(MemoryManager);

end.
person user3863403    schedule 27.07.2014
comment
Ты такой подлый. Это именно то, что мы говорили вам делать снова и снова. Это даже мой код! И вы плохо экспортировали функции. Сделайте это с файлом .def. И вы не ответили на все вопросы. Ответы предназначены для решения вопроса, который был задан. И вы не правильно отформатировали код. Ты действительно что-то. - person David Heffernan; 27.07.2014
comment
Прочитайте вопрос. Где вы просили подробное решение? И насколько ваш ответ отличается от моего? Я предположил, что вы способны создавать DLL и экспортировать функции. Я не понимал, что вам нужно сказать, как это сделать. Что-то хорошо задокументированное. А у тебя плохо получилось. Сделайте это с файлом .def, чтобы напрямую экспортировать функции. Вы не ответили на все вопросы. Вы не форматировали код. Это код, который я написал в любом случае! - person David Heffernan; 27.07.2014
comment
@DavidHeffernan Верно. - person user3863403; 27.07.2014
comment
Нет особого смысла в том, чтобы мы пытались помочь. Вы, кажется, не хотите нас слушать. Почему бы вам просто не экспортировать malloc, realloc и free? И если вы собираетесь публиковать чужой код, указывайте его авторство, иначе это будет выглядеть так, как будто вы выдаете его за свой собственный. - person David Heffernan; 27.07.2014