Realloc()无法正确释放Windows中的内存

ash*_*fie 6 memory windows realloc

我试图在Windows应用程序中使用realloc().我正在分配一大块内存,然后在我知道正确的大小后使用realloc()将其缩小.

我发现虽然realloc()似乎工作正常(任务管理器中的内存反映了你的期望),但应用程序最终会耗尽内存.从我所知道的情况来看,就好像relloc()释放内存但不释放与内存关联的虚拟地址空间.结果,malloc()最终会失败.

这是一个小型控制台应用程序,用于演示此问题:

int _tmain(int argc, _TCHAR* argv[])
{
    static const DWORD dwAllocSize = (50 * 1024 * 1024);
    static const DWORD dwReallocSize = 10240;
    static const DWORD dwMaxIterations = 200;

    BYTE* arpMemory[dwMaxIterations];
    memset( arpMemory, 0, sizeof(arpMemory) );

    for( DWORD i = 0; i < dwMaxIterations; i++ )
    {
        arpMemory[i] = (BYTE*) malloc( dwAllocSize );
        if( !arpMemory[i] )
        {
            printf("OUT OF MEMORY after %d iterations!\n", i);
            return -1;
        }

        BYTE* pRealloc = (BYTE*) realloc( arpMemory[i], dwReallocSize );
        if( !pRealloc )
        {
            printf("Realloc FAILED after %d iterations!\n", i);
            return -1;
        }
        else if( pRealloc != arpMemory[i] )
        {
            printf("Warning: Pointer changed: 0x%08X -> 0x%08X\n", arpMemory[i], pRealloc);
            arpMemory[i] = pRealloc;
        }
    }

    printf("Success!\n");

    for( int i = 0; i < dwMaxIterations; i++ )
        free( arpMemory[i] );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该应用程序重复分配50 MB的内存,然后立即调整大小只有10K.如果你运行它,你会发现它仅在38次迭代后失败并出现OUT OF MEMORY错误.这相当于2GB最初分配的内存 - 这是Windows应用程序的地址空间限制.

有趣的是,如果你查看任务管理器,你会看到应用程序几乎没有任何内存.然而malloc()失败了.这就是让我相信虚拟地址空间耗尽的原因.

(尝试的另一个实验是注释掉重新分配,因此没有内存被释放或重新分配.应用程序在完全相同的位置失败:经过38次迭代.唯一的区别是这次任务管理器反映了正在使用的完整2GB.)

最后一点信息:这个应用程序在Linux下运行.所以这个realloc()问题严格来说只限于Windows.

有什么想法吗?

Han*_*ant 4

这样做会使堆碎片化。无论您使用 realloc() 释放什么,都会添加到空闲块列表中。永远不会再次使用,因为你总是要求一个比这更大的新块。这些空闲块只会累积占用虚拟内存,直到没有剩余为止。当您一次丢弃近 50 MB 的数据时,这种情况很快就会发生。

您需要重新考虑您的方法。