Find largest free memory block
delphi, memory-management
Solution
This is the translation to Delphi code that you wanted:
function GetLargestFreeMemRegion(var AAddressOfLargest: pointer): LongWord;
var
Si: TSystemInfo;
P, dwRet: LongWord;
Mbi: TMemoryBasicInformation;
begin
Result := 0;
AAddressOfLargest := nil;
GetSystemInfo(Si);
P := 0;
while P < LongWord(Si.lpMaximumApplicationAddress) do begin
dwRet := VirtualQuery(pointer(P), Mbi, SizeOf(Mbi));
if (dwRet > 0) and (Mbi.State and MEM_FREE <> 0) then begin
if Result < Mbi.RegionSize then begin
Result := Mbi.RegionSize;
AAddressOfLargest := Mbi.BaseAddress;
end;
Inc(P, Mbi.RegionSize);
end else
Inc(P, Si.dwPageSize);
end;
end;
You can use it like this:
procedure TForm1.FormCreate(Sender: TObject);
var
BaseAddr: pointer;
MemSize: LongWord;
begin
MemSize := GetLargestFreeMemRegion(BaseAddr);
// allocate dynamic array of this size
SetLength(fArrayOfBytes, MemSize - 16);
Caption := Format('Largest address block: %u at %p; dynamic array at %p',
[MemSize, BaseAddr, pointer(@fArrayOfBytes[0])]);
end;
Note that I had to subtract 16 bytes from the maximum size, presumably because the dynamic array itself uses a few bytes which were allocated from the same chunk of memory, so the next allocation was based on the next multiple of 16.
Problem
There is sometimes a problem with running out of memory when it got fragmented. Is it possible to find the largest free memoryblock ? I use Delphi 2007 with FastMM. Developing on Windows XP running app on Windows 2003. Regards EDIT: I could add the info that the app is running on a server with 32 GB memory on a Windows Server 2003 x64. But the app is a 32 bit application so the theoretical max allocated memory for each instance is 2 GB. Many instances is run at once. I do not think it is the total physical memory that is to little. I guess when started the app got a 32 bit virtual memory space. This can then be too fragmented during runtime. I also found the method FastGetHeapStatus that returns a THeapStatus with some fields for free memory. Maybe I could use those. EDIT2: I found this How to get the largest available continues memory block. The code is C but maybe it could be translated to Delphi.