Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't my program's memory usage return to normal after I free memory?

consider the next sample application

program TestMemory;


{$APPTYPE CONSOLE}

uses
  PsAPI,
  Windows,
  SysUtils;

function GetUsedMemoryFastMem: cardinal;
var
    st: TMemoryManagerState;
    sb: TSmallBlockTypeState;
begin
    GetMemoryManagerState(st);
    result := st.TotalAllocatedMediumBlockSize + st.TotalAllocatedLargeBlockSize;
    for sb in st.SmallBlockTypeStates do
    begin
        result := result + sb.UseableBlockSize * sb.AllocatedBlockCount;
    end;
end;

function GetUsedMemoryWindows: longint;
var
  ProcessMemoryCounters: TProcessMemoryCounters;
begin
  Result:=0;
  ProcessMemoryCounters.cb := SizeOf(TProcessMemoryCounters);
  if GetProcessMemoryInfo(GetCurrentProcess(), @ProcessMemoryCounters, ProcessMemoryCounters.cb) then
   Result:= ProcessMemoryCounters.WorkingSetSize
  else
   RaiseLastOSError;
end;

procedure Test;
const
  Size = 1024*1024;
var
  P : Pointer;
begin
  GetMem(P,Size);

      Writeln('Inside');
      Writeln('FastMem '+FormatFloat('#,', GetUsedMemoryFastMem));
      Writeln('Windows '+FormatFloat('#,', GetUsedMemoryWindows));
      Writeln('');

  FreeMem(P);
end;

begin
      Writeln('Before');
      Writeln('FastMem '+FormatFloat('#,', GetUsedMemoryFastMem));
      Writeln('Windows '+FormatFloat('#,', GetUsedMemoryWindows));
      Writeln('');

      Test;

      Writeln('After');
      Writeln('FastMem '+FormatFloat('#,', GetUsedMemoryFastMem));
      Writeln('Windows '+FormatFloat('#,', GetUsedMemoryWindows));
      Writeln('');
      Readln;
end.

the results returned by the app are

Before
FastMem 1.844
Windows 3.633.152

Inside
FastMem 1.050.612
Windows 3.637.248

After
FastMem 2.036
Windows 3.633.152

I wanna know why the results of the memory usage are different in the Before and After:

like image 701
Salvador Avatar asked Dec 15 '10 08:12

Salvador


2 Answers

Any memory manager (including FastMM) incurs some overhead, otherwise Delphi could have just used the Windows memory management.

The difference you observe is the overhead:

  • structures that FastMM uses to keep track of memory usage,
  • pieces of memory that FastMM did not yet return to the Windows memory management to optimize similar memory allocations in the future.
like image 165
Jeroen Wiert Pluimers Avatar answered Oct 30 '22 21:10

Jeroen Wiert Pluimers


Because the memory manager is doing clever things in the background to speed up performance.

like image 40
Optimal Cynic Avatar answered Oct 30 '22 21:10

Optimal Cynic