找到最大的内存分配

时间:2011-01-13 11:17:05

标签: c++ c windows malloc new-operator

在32位模式下,应用程序可以访问2GB的虚拟地址空间。您如何找到可以分配给此虚拟地址空间的最大内存大小,而没有malloc或新的失败?

例如,假设您想要占用整个2GB的虚拟地址空间,但您只是在2GB地址空间的中间分配了2MB的数据。是否有Windows API调用,您可以找到可以分配的最大并发地址空间?那么当你调用malloc或new时,调用不会失败?

感谢您的时间。

3 个答案:

答案 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