Watching heap memory usage in Free Pascal/Delphi

| category: Testing | author: st
Tags: ,

Free Pascal (like Delphi) provide some useful functions to watch heap memory state in your application.

function GetHeapStatus: THeapStatus;

THeapStatus is documented here

Example of using this function is below

program ProgWatchMem;

uses
  Math, FGL;

type
  TLongIntArr = array of LongInt; // LongInt is a 4-byte signed integer
  PLongIntArr = ^TLongIntArr;
  TMySortedMap = specialize TFPGMap<LongInt, LongInt>;

procedure WatchArrayMemory(const Count: integer);
var
  p: PLongIntArr;
  m1, m2, m3, m4, m5: integer;
begin
  writeln('-------------------');
  writeln('Testing TLongIntArr, length: ', Count);
  writeln('-------------------');
  m1 := GetHeapStatus.TotalAllocated;
  writeln('Total heap memory allocated, bytes: ', m1);
  p := new(PLongIntArr);
  m2 := GetHeapStatus.TotalAllocated;
  writeln('Empty. Size: ', m2 - m1);
  SetLength(p^, Count);
  m3 := GetHeapStatus.TotalAllocated;
  writeln('Allocated. Size: ', m3 - m1);
  SetLength(p^, 0);
  m4 := GetHeapStatus.TotalAllocated;
  writeln('Truncated. Size: ', m4 - m1);
  Dispose(p);
  m5 := GetHeapStatus.TotalAllocated;
  writeln('Total heap memory (after disposing): ', m5);
end;

procedure WatchFPGMapMemory(const Count: integer);
var
  Dic: TMySortedMap;
  i, m1, m2, m3, m4, m5: integer;
begin
  writeln('-------------------');
  writeln('Testing TMySortedMap, length: ', Count);
  writeln('-------------------');
  m1 := GetHeapStatus.TotalAllocated;
  writeln('Total heap memory allocated, bytes: ', m1);
  Dic := TMySortedMap.Create;
  m2 := GetHeapStatus.TotalAllocated;
  writeln('Empty. Size: ', m2 - m1);
  for i := 1 to Count do
    Dic.Add(Math.RandomRange(1, Count), Math.RandomRange(-100000000, 100000000));
  m3 := GetHeapStatus.TotalAllocated;
  writeln('Filled test data. Size: ', m3 - m1);
  Dic.Sorted := true;
  m3 := GetHeapStatus.TotalAllocated;
  writeln('Sorted data. Size: ', m3 - m1);
  Dic.Clear;
  m4 := GetHeapStatus.TotalAllocated;
  writeln('Cleared. Size: ', m4 - m1);
  Dic.Free;
  m5 := GetHeapStatus.TotalAllocated;
  writeln('Total heap memory (after disposing): ', m5);
end;

begin
  WatchArrayMemory(1000);
  WatchArrayMemory(10000);
  WatchFPGMapMemory(1000);
  WatchFPGMapMemory(10000);
end.

Results:

-------------------
Testing TLongIntArr, length: 1000
-------------------
Total heap memory allocated, bytes: 1280
Empty. Size: 32
Allocated. Size: 4096
Truncated. Size: 32
Total heap memory (after disposing): 1280
-------------------
Testing TLongIntArr, length: 10000
-------------------
Total heap memory allocated, bytes: 1280
Empty. Size: 32
Allocated. Size: 40096
Truncated. Size: 32
Total heap memory (after disposing): 1280
-------------------
Testing TMySortedMap, length: 1000
-------------------
Total heap memory allocated, bytes: 1280
Empty. Size: 128
Filled test data. Size: 9344
Sorted data. Size: 9344
Cleared. Size: 160
Total heap memory (after disposing): 1280
-------------------
Testing TMySortedMap, length: 10000
-------------------
Total heap memory allocated, bytes: 1280
Empty. Size: 128
Filled test data. Size: 89728
Sorted data. Size: 89728
Cleared. Size: 160
Total heap memory (after disposing): 1280