查找最大的可用内存块 [英] Find largest free memory block
问题描述
有时碎片会耗尽内存.
是否可以找到最大的空闲内存块? 我将Delphi 2007与FastMM一起使用.在Windows 2003上运行Windows XP的应用程序上进行开发.
致谢
我可以添加有关该应用程序正在Windows Server 2003 x64上具有32 GB内存的服务器上运行的信息.但是该应用程序是32位应用程序,因此每个实例的理论上最大分配内存为2 GB.一次运行许多实例.我认为总的物理内存不足.我猜想启动该应用程序时会获得32位虚拟内存空间.这样在运行时可能会变得过于分散.
我还找到了FastGetHeapStatus方法,该方法返回一个THeapStatus以及一些用于释放内存的字段.也许我可以用那些.
我发现了这个如何获取最大的可用连续内存块. 代码是C,但也许可以将其翻译为Delphi.
这是您想要的Delphi代码翻译:
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;
您可以像这样使用它:
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;
请注意,我必须从最大大小中减去16个字节,大概是因为动态数组本身使用了从同一块内存中分配的几个字节,所以下一个分配基于下一个16的倍数. /p>
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.
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.
这篇关于查找最大的可用内存块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!