7
votes

How could I get the total amount of memory, that allocated by FastMM?

I've tried that:

function GetTotalAllocatedMemory: Cardinal;
var
  MMState: TMemoryManagerState;
begin
  GetMemoryManagerState(MMState);
  Result := MMState.TotalAllocatedMediumBlockSize + MMState.TotalAllocatedLargeBlockSize;
end;

Is it correct?

Anyways it returns something strange. It 5 times less than a value which I can see in Windows task manager. I believe that the amount of memory allocated by a Delphi application equals FastMM allocated memory plus some system overhead. Am I wrong?

4
What are you comparing to from Task Manager? Tell us the column name, so we can tell you why your results are correct.Cosmin Prund
GetTotalAllocatedMemory returns 13,973,184 / taskmanager's "Mem Usage" column now shows 154,912KRoman Yankovsky
Cosmin means to which column in Task Manager are you comparing the result of GetTotalAllocatedMemory?Remko
"Mem Usage" column on "Processes" page.Roman Yankovsky
@Roman consider for a minute that the FastMM usage tracker contains source code for how the FastMM authors feel is the right way to report usage. If you want to know how to do it right then I can't see a better source than this.David Heffernan

4 Answers

4
votes

Use this:

//------------------------------------------------------------------------------  
// CsiGetApplicationMemory  
//  
// Returns the amount of memory used by the application (does not include  
// reserved memory)  
//------------------------------------------------------------------------------  
function CsiGetApplicationMemory: Int64;  
var  
  lMemoryState: TMemoryManagerState;  
  lIndex: Integer;  
begin  
  Result := 0;  

  // get the state  
  GetMemoryManagerState(lMemoryState);  

  with lMemoryState do begin  
    // small blocks  
    for lIndex := Low(SmallBlockTypeStates) to High(SmallBlockTypeStates) do  
      Inc(Result,  
          SmallBlockTypeStates[lIndex].AllocatedBlockCount *  
          SmallBlockTypeStates[lIndex].UseableBlockSize);  

    // medium blocks  
    Inc(Result, TotalAllocatedMediumBlockSize);  

    // large blocks  
    Inc(Result, TotalAllocatedLargeBlockSize);  
  end;  
end;
4
votes

You are comparing apples and oranges.

FastMM memory is netto usage of memory allocated through FastMM.

This does not include at least these:

  • FastMM overhead
  • Windows overhead of blocks allocated by FastMM on your behalf
  • Windows overhead of things not allocated by FastMM (like the space occupied by DLL's in your process space)
  • for GUI apps: overhead of GDI, GDI+, DirectX, OpenGL and other storage for visual objects allocated on your behalf.

--jeroen

3
votes

For the process memory use this:

//------------------------------------------------------------------------------
// CsiGetProcessMemory
//
// Return the amount of memory used by the process
//------------------------------------------------------------------------------
function CsiGetProcessMemory: Int64;
var
  lMemoryCounters: TProcessMemoryCounters;
  lSize: Integer;
begin
  lSize := SizeOf(lMemoryCounters);
  FillChar(lMemoryCounters, lSize, 0);
  if GetProcessMemoryInfo(CsiGetProcessHandle, @lMemoryCounters, lSize) then
    Result := lMemoryCounters.PageFileUsage
  else
    Result := 0;
end;
3
votes

I also have faced this situation:

Anyways it returns something strange. It 5 times less than a value which I can see in Windows task manager. I believe that the amount of memory allocated by a Delphi application equals FastMM allocated memory plus some system overhead. Am I wrong?

and wasted several hours trying to find out where all the memory is. My app occupied 170 Mb according to Task manager but FastMM's stats was showing total size of allocated blocks ~13 Mb:

12565K Allocated
160840K Overhead
7% Efficiency

(excerpt from FastMM LogMemoryManagerStateToFile procedure output). Finally I realized that this enormous overhead is caused by FullDebug mode. It keeps stacktraces for every allocation so if you've many tiny memory blocks allocated (my app had UnicodeString x 99137, Unknown x 17014 and ~10000 of Xml objects) the overhead becomes frightening. Removing FullDebug mode returned memory consumption to its normal values.

Hope this help somebody.