program test_mem;
{$IfDef FPC}
{$Mode DelphiUnicode}
{$H+}
{$EndIf}
uses
{$IfDef Unix}
cthreads,
{$EndIf}
Classes;
// Test array
var Q: array of Byte;
// Memory manager and heap status to get some feedback from MM
var MemMng: TMemoryManager;
HeapStatus: TFPCHeapStatus;
// Thread function to finalize array
procedure ThreadFunc;
begin
// Just to see that function runs
WriteLn('ThreadFunc is running');
// And finalizes the array
Q := nil;
end;
var T: TThread;
begin
GetMemoryManager(MemMng);
// Setting array to some size (10 GB in this case)
SetLength(Q, 10000000000);
WriteLn('Array is filled');
// Wait for a user press (to profile with task manager/htop/etc)
ReadLn;
// Create thread that will finalize the array
T := TThread.CreateAnonymousThread(ThreadFunc);
T.FreeOnTerminate := False;
T.Start;
// And wait for it to finish
T.WaitFor;
WriteLn('Array should be empty after that');
ReadLn;
// (1) Get status of heap after thread "deallocated" memory
HeapStatus := MemMng.GetFPCHeapStatus;
WriteLn('MaxHeapSize ', HeapStatus.MaxHeapSize);
WriteLn('MaxHeapUsed ', HeapStatus.MaxHeapUsed);
WriteLn('CurrHeapSize ', HeapStatus.CurrHeapSize);
WriteLn('CurrHeapUsed ', HeapStatus.CurrHeapUsed);
WriteLn('CurrHeapFree ', HeapStatus.CurrHeapFree);
// And we try to make the array of the same size again
SetLength(Q, 10000000000);
// (2) And then get status of heap immediately after
HeapStatus := MemMng.GetFPCHeapStatus;
WriteLn('MaxHeapSize ', HeapStatus.MaxHeapSize);
WriteLn('MaxHeapUsed ', HeapStatus.MaxHeapUsed);
WriteLn('CurrHeapSize ', HeapStatus.CurrHeapSize);
WriteLn('CurrHeapUsed ', HeapStatus.CurrHeapUsed);
WriteLn('CurrHeapFree ', HeapStatus.CurrHeapFree);
// Wait for a user to press Enter
ReadLn;
// And finalize array
Q := nil;
// (3) Again, get status of heap
HeapStatus := MemMng.GetFPCHeapStatus;
WriteLn('MaxHeapSize ', HeapStatus.MaxHeapSize);
WriteLn('MaxHeapUsed ', HeapStatus.MaxHeapUsed);
WriteLn('CurrHeapSize ', HeapStatus.CurrHeapSize);
WriteLn('CurrHeapUsed ', HeapStatus.CurrHeapUsed);
WriteLn('CurrHeapFree ', HeapStatus.CurrHeapFree);
ReadLn;
T.Free;
WriteLn('Thread destroyed');
ReadLn;
end.