Every compiler has its own memory management system. And, to be accurate, you can have several MM working on the same compiler. You can choose which MM to use, depending on your application purpose. For instance, in a Server you may be interested in a multi-thread scaling MM, but on a simple UI Client application, you'd like your MM just to be fast and not memory consuming.
The internal Heap management provided by Windows was so slow (at least until XP) that every compiler/framework did implement its own memory manager.
For Delphi, there was a "pure Borland" version since 2006, then an Open Source MM, named FastMM4, has been included into the main "Delphi" IDE.
With Delphi, it's very easy to change the memory manager. You just create a record of functions, then call the SetMemoryManager() to replace the current MM with the new one.
For instance, here is how is installed our Open Source scaling Memory Manager for Delphi:
{$if CompilerVersion >= 17}
{$define USEMEMMANAGEREX}
{$ifend}
var
{$ifdef USEMEMMANAGEREX}
OldMM: TMemoryManagerEx;
{$else}
OldMM: TMemoryManager;
{$endif}
const
{$ifdef USEMEMMANAGEREX}
ScaleMM_Ex: TMemoryManagerEx = (
GetMem: Scale_GetMem;
FreeMem: Scale_FreeMem;
ReallocMem: Scale_ReallocMem;
AllocMem: Scale_AllocMem;
RegisterExpectedMemoryLeak: Scale_RegisterMemoryLeak;
UnregisterExpectedMemoryLeak: Scale_UnregisterMemoryLeak );
{$else}
ScaleMM_Ex: TMemoryManager = (
GetMem: Scale_GetMem;
FreeMem: Scale_FreeMem;
ReallocMem: Scale_ReallocMem );
{$endif}
procedure ScaleMMInstall;
begin
// Hook memory Manager
GetMemoryManager(OldMM);
if @OldMM <> @ScaleMM_Ex then
SetMemoryManager(ScaleMM_Ex);
// init main thread manager
GlobalManager.Init;
This code will replace the Delphi MM by our own, via the custom Scale_GetMem
/ Scale_FreeMem
/ Scale_ReallocMem
/ Scale_AllocMem
functions. You can just make a wrapper to the old MM by using the OldMM
variable:
function Scale_GetMem(aSize: Integer): Pointer;
begin
// do some debugging here
result := OldMM.GetMem(aSize);
end;
The MM record structure changed in time, so you'll have to select the right one - we do this using the USEMEMMANAGEREX
conditional.