Realloc()不能正确释放Windows中的内存 [英] Realloc() does not correctly free memory in Windows

查看:183
本文介绍了Realloc()不能正确释放Windows中的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to use realloc() in a Windows application. I am allocating a large block of memory, then using realloc() to shrink it down later once I know the correct size.

我发现,尽管 realloc()似乎可以正常工作(任务管理器中的内存反映了您的期望),但应用程序最终会用尽内存.据我所知,好像 relloc()释放了内存,但没有释放与该内存关联的虚拟地址空间.结果, malloc()最终将失败.

I am finding that although realloc() appears to work correctly (memory in Task Manager reflects what you would expect) the application eventually runs out of memory. From what I can tell, it's as though relloc() frees the memory but does not free the virtual address space associated with the memory. As a result, malloc() will eventually fail.

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

Here's a small console app that demonstrates the problem:

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;
}

该应用程序反复分配50 MB的内存,然后立即将其大小调整为仅10K.如果运行它,您将发现它仅经过38次迭代就会失败,并出现内存不足错误.这相当于2GB的最初分配的内存-这是Windows应用程序的地址空间限制.

The app repeatedly allocates 50 MB of memory and then immediately resizes it to be only 10K. If you run it, you will find that it fails with an OUT OF MEMORY error after only 38 iterations. This corresponds to 2GB of originally allocated memory -- which is the address space limit for Windows applications.

有趣的是,如果您在任务管理器中查看,您将看到该应用程序几乎不占用任何内存.但是 malloc()失败了.这就是让我相信虚拟地址空间已耗尽的原因.

Interestingly, if you look in Task Manager, you will see the application taking almost no memory at all. Yet malloc() is failing. This is what leads me to believe the virtual address space is being exhausted.

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

(Another experiment to try is to comment out the reallocation, so no memory is freed or reallocated. The app fails in exactly the same place: After 38 iterations. The only difference is that this time Task Manager reflects the full 2GB in use.)

最后一个信息点:该应用程序在Linux下工作.因此,这个 realloc()问题严格来说仅适用于Windows.

One final point of information: This same application works under Linux. So this realloc() problem is strictly Windows-only.

有什么想法吗?

推荐答案

您正在对堆进行分段操作.使用realloc()释放的所有内容都会添加到空闲块列表中.永远不要再使用它,因为您总是要求一个更大的新块.这些可用的块只会累积占用的虚拟内存,直到没有剩余的可用空间为止.一次丢掉近50兆字节时,发生的速度很快.

You are fragmenting the heap doing this. Whatever you release with realloc() gets added to the list of free blocks. Never to be used again because you always ask for a new block that's larger than that. These free blocks will just accumulate taking up virtual memory until no more is left. Happens pretty quickly when you throw away almost 50 megabytes at a time.

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

You'll need to rethink your approach.

这篇关于Realloc()不能正确释放Windows中的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆