开发者

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('F开发者_如何学CastMem '+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:


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.


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


How does it work getmem/malloc/free?

Heap Allocator - As used by malloc...

1) Internally allocates large chunks(typically 64K up to 1Megabyte) of memory and then sub-divides the chunks up to give you the 100byte and 200byte objects and strings in the program. When you free memory all that happens is the place where it was allocated from in the internal buffer or chunk is then marked as free. NOTHING ACTUALLY HAPPENS!

2) So you can think of the HEAP as a list of big chunks of memory, and all the objects in your program are just little parts of those chunks.

3) The big internal chunks of memory are only freed when all the objects inside them have been freed, so the usual case is that when you free some object that nothing actually happens except some bits get marked as being available.

That is a fairly naive description of the heap system, but most heaps work in a similar way, but do a lot more optimization than that. But your question is why does the memory not go down and the answer is because nothing actually gets freed. The internal pages of memory are retained for the next call to "new" or "malloc" etc...

PICTURE IT

INSIDE HEAP IS ONE HUGE BLOCK OF 100Kb

You call "malloc(1000)" or "getmem(1000)" to get a 1K block of memory.

Then all that happens is that the 1K block of memory is taken from the 100kb block of memory leaving 99K of memory available in that block. If you keep calling malloc or getmem then it will just keep dividing the larger block up until it needs another larger block.

Each little block of memory allocated with a call to malloc or getmem actually gets about 16 or 24 extra bytes(depending on allocator) extra memory. That memory is bits that the allocator uses to know what is allocated and also where it is allocated.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜