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

delphi, delphi-2007

Solution

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.

Problem

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`:

Original source

Related problems