RAD Studio VCL Reference
ContentsIndex
PreviousUpNext
System.GetMemoryManager Function

Returns the entry points of the currently installed memory manager.

Pascal
procedure GetMemoryManager(var MemMgr: TMemoryManager); overload; deprecated;
procedure GetMemoryManager(var MemMgrEx: TMemoryManagerEx); overload;
C++
GetMemoryManager(TMemoryManager MemMgr);
GetMemoryManager(TMemoryManagerEx MemMgrEx);

GetMemoryManager returns the entry points of the currently installed memory manager in a TMemoryManager record.  

C++ Examples: 

 

/*
This example demonstrates the use of SetMemoryManager and
GetMemoryManager routines. Note that this example is
thread safe.
*/

bool isMyMemMgr;
TMemoryManagerEx oldMemMgr;
volatile long getMemCalls;
volatile long freeMemCalls;
volatile long reallocMemCalls;
volatile long allocMemCalls;

void* __fastcall myGetMem(int size)
{
    //safely increment the counter
    InterlockedIncrement(&getMemCalls);

    //route the call
    return oldMemMgr.GetMem(size);
}

int __fastcall myFreeMem(void* p)
{
    //safely increment the counter
    InterlockedIncrement(&freeMemCalls);

    //route the call
    return oldMemMgr.FreeMem(p);
}

void* __fastcall myReallocMem(void* p, int size)
{
    //safely increment the counter
    InterlockedIncrement(&reallocMemCalls);

    //route the call
    return oldMemMgr.ReallocMem(p, size);
}

void* __fastcall myAllocMem(int size)
{
    //safely increment the counter
    InterlockedIncrement(&allocMemCalls);

    //route the call
    return oldMemMgr.AllocMem(size);
}

void __fastcall TForm3::btUseSysMemMgrClick(TObject *Sender)
{
    //switch button states
    btUseSysMemMgr->Enabled = false;
    btUseMyMemMgr->Enabled = true;

    //set the old memory manager back
    SetMemoryManager(oldMemMgr);

    isMyMemMgr = false;

    //clear out the variables
    getMemCalls     = 0;
    freeMemCalls    = 0;
    reallocMemCalls = 0;
    allocMemCalls   = 0;
}

void __fastcall TForm3::FormDestroy(TObject *Sender)
{
    //set the old memory manager back
    if (isMyMemMgr)
    {
        SetMemoryManager(oldMemMgr);
    }
}

void __fastcall TForm3::Timer1Timer(TObject *Sender)
{
    //Note that IntToStr calls will also Allocate/Free
    //memory so at each timer tick the counts will be +4;

    Form3->edGetMem->Text = IntToStr((int)getMemCalls);
    Form3->edFreeMem->Text = IntToStr((int)freeMemCalls);
    Form3->edReallocMem->Text = IntToStr((int)reallocMemCalls);
    Form3->edAllocMem->Text = IntToStr((int)allocMemCalls);
}

void __fastcall TForm3::btUseMyMemMgrClick(TObject *Sender)
{
    TMemoryManagerEx myMemMgr;

    //switch button states
    btUseSysMemMgr->Enabled = true;
    btUseMyMemMgr->Enabled = false;

    //get the old memory manager
    GetMemoryManager(oldMemMgr);

    //create out instance
    myMemMgr.GetMem = myGetMem;
    myMemMgr.FreeMem = myFreeMem;
    myMemMgr.AllocMem = myAllocMem;
    myMemMgr.ReallocMem = myReallocMem;

    //use defaults for this - not important
    myMemMgr.RegisterExpectedMemoryLeak = oldMemMgr.RegisterExpectedMemoryLeak;
    myMemMgr.UnregisterExpectedMemoryLeak = oldMemMgr.UnregisterExpectedMemoryLeak;

    //clear out the variables
    getMemCalls     = 0;
    freeMemCalls    = 0;
    reallocMemCalls = 0;
    allocMemCalls   = 0;

    //install the new memory manager
    SetMemoryManager(myMemMgr);

    isMyMemMgr = true;
}

void __fastcall TForm3::btDoSomethingClick(TObject *Sender)
{
    void *ptr;
    //perform some new and delete
    for (int i=0; i < 1000; ++i)
    {
        ptr = GetMemory(4);
        FreeMemory(ptr);
    }
}

 

Delphi Examples: 

{
This example demonstrates the use of SetMemoryManager and
GetMemoryManager routines. Note that this example is
thread safe.
}
var
  OldMemMgr       : TMemoryManagerEx;
  GetMemCalls     : Integer;
  FreeMemCalls    : Integer;
  ReallocMemCalls : Integer;
  AllocMemCalls   : Integer;

function MyGetMem(Size: Integer): Pointer;
begin
  { Route the call }
  Result := OldMemMgr.GetMem(Size);

  { Safely increment the counter }
  InterlockedIncrement(GetMemCalls);
end;

function MyFreeMem(P: Pointer): Integer;
begin
  { Route the call }
  Result := OldMemMgr.FreeMem(P);

  { Safely increment the counter }
  InterlockedIncrement(FreeMemCalls);
end;

function MyReallocMem(P: Pointer; Size: Integer): Pointer;
begin
  { Route the call }
  Result := OldMemMgr.ReallocMem(P, Size);

  { Safely increment the counter }
  InterlockedIncrement(ReallocMemCalls);
end;

function MyAllocMem(Size: Cardinal): Pointer;
begin
  { Route the call }
  Result := OldMemMgr.AllocMem(Size);

  { Safely increment the counter }
  InterlockedIncrement(AllocMemCalls);
end;

procedure TForm2.btPerformSomethingClick(Sender: TObject);
var
  X : Integer;
  I : ^Integer;
begin
  { Perform some allocations and frees }
  for X := 0 to 999 do
  begin
    New(I);
    Dispose(I);
  end;
end;

procedure TForm2.btUseMyMemMgrClick(Sender: TObject);
var
  MyMemMgr : TMemoryManagerEx;
begin
  { Switch button states }
  btUseSystemMemMgr.Enabled := true;
  btUseMyMemMgr.Enabled := false;

  { Get the old memory manager }
  GetMemoryManager(OldMemMgr);

  { Create our instance }
  MyMemMgr.GetMem := MyGetMem;
  MyMemMgr.FreeMem := MyFreeMem;
  MyMemMgr.ReallocMem := MyReallocMem;
  MyMemMgr.AllocMem := MyAllocMem;

  { Use the defaults for this - not important }
  MyMemMgr.RegisterExpectedMemoryLeak := OldMemMgr.RegisterExpectedMemoryLeak;
  MyMemMgr.UnregisterExpectedMemoryLeak := OldMemMgr.UnregisterExpectedMemoryLeak;

  { Clear out the count variables }
  GetMemCalls := 0;
  FreeMemCalls := 0;
  ReallocMemCalls := 0;
  AllocMemCalls := 0;

  { Install the new memory manager }
  SetMemoryManager(MyMemMgr);
end;

procedure TForm2.btUseSystemMemMgrClick(Sender: TObject);
begin
  { Switch button states }
  btUseSystemMemMgr.Enabled := false;
  btUseMyMemMgr.Enabled := true;

  { Set the old memory manager back! }
  SetMemoryManager(OldMemMgr);

  GetMemCalls := 0;
  FreeMemCalls := 0;
  ReallocMemCalls := 0;
  AllocMemCalls := 0;
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  { Set the old memory manager back }
  if IsMemoryManagerSet then
     SetMemoryManager(OldMemMgr);
end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
  {
  Note that IntToStr calls will also Allocate/Free
  memory so at each timer tick the counts will be increased;
  }
  Form2.edtGetMemCalls.Text := IntToStr(GetMemCalls);
  Form2.edtFreeMemCalls.Text := IntToStr(FreeMemCalls);
  Form2.edtReallocMemCalls.Text := IntToStr(ReallocMemCalls);
  Form2.edtAllocMemCalls.Text := IntToStr(AllocMemCalls);
end;

 

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!