在32位模式下,应用程序可以访问2GB的虚拟地址空间。您如何找到可以分配给此虚拟地址空间的最大内存大小,而没有malloc或新的失败?
例如,假设您想要占用整个2GB的虚拟地址空间,但您只是在2GB地址空间的中间分配了2MB的数据。是否有Windows API调用,您可以找到可以分配的最大并发地址空间?那么当你调用malloc或new时,调用不会失败?
感谢您的时间。
答案 0 :(得分:6)
来源: http://www.voyce.com/index.php/2009/08/21/largest-free-block-of-address-space/
DWORD FindLargestSizeOfMemory()
{
MEMORY_BASIC_INFORMATION mbi;
DWORD start = 0;
bool recording = false;
DWORD freestart = 0, largestFreestart = 0;
__int64 free = 0, largestFree = 0;
while (true)
{
SIZE_T s = VirtualQuery((LPCVOID)start, &mbi, sizeof(mbi));
if (s != sizeof(mbi)) break;
if (mbi.State == MEM_FREE)
{
if (!recording) freestart = start;
free += mbi.RegionSize;
recording = true;
}
else
{
if (recording)
{
if (free > largestFree)
{
largestFree = free;
largestFreestart = freestart;
}
}
free = 0;
recording = false;
}
start += mbi.RegionSize;
}
return largestFree;
}
答案 1 :(得分:1)
你可能永远得不到满意的答案。最大的可分配内存块取决于内存碎片,可以通过内存碎片整理工具,不同的内存管理器,不同的启动时间开关(例如Windows上的/ 3GB)甚至重新启动来更改。
我不确定你的意思是“没有malloc或新的失败”,你有没有访问malloc?因为正确的方法是在递增步骤中使用var = malloc(...)分配内存并查找var为null的步骤。
我很确定您所寻求的信息只能通过探测来确定。通过分配和释放正在运行的进程,信息始终处于流畅的运动状态,它只能是当前情况的快照,当然,为了拍摄快照,所有进程都必须暂时暂停。因此,Windows扫描结果并将其返回给您后所获得的信息将不准确或有弹性,因为内存分配的结构现在很可能已经改变。
答案 2 :(得分:0)
您可以使用VirtualQuery功能查询可能的网页,看看他们是否返回MEM_FREE
。