分配ram显示任务管理器中ram使用量的两倍

时间:2011-07-11 19:11:49

标签: c windows-7 malloc

做一些分析(记忆和速度)我已经被win7似乎分配了我要求的RAM的两倍......这注意这是我第一次在win7上进行这样的活动分析,所以我真的不知道会发生什么。

我在win7(64位)下使用MSVC的快速版本在循环中分配精确数量的RAM。该应用程序已编译并以32位运行。

我分配了24 MB的ram,任务管理器将我的应用程序显示为使用48MB(在所有内存列下,包括已提交,因为我实际上是在新区域内进行memcopy)。当我得到24个(现在应该是48MB)时,我的应用程序会跳到96等等。

这些被分配为1,000,000个24字节结构。

我在网上搜索过,但没有找到任何与我的观察结果完全匹配的内容。

任何人都有线索?

如果这只是操作系统欺骗(或无能?),是否有任何工具可以给我一个进程的实际内存消耗? (很难找到泄漏,当应用程序开始时; - )

[-----------编辑,附加信息-----------]

注意(通过控制台标题栏中的路径)我在发布模式下构建(使用MSVC 2010的所有默认“空”项目设置),因此没有分配额外的“调试”内存(可以是在某些项目中相当广泛。)

这是一个简短,完整的C应用程序,用于说明行为:

#include <stdio.h>
#include <assert.h>
#include <conio.h>
#include <stdlib.h>
typedef unsigned int u32;
typedef struct myStruct MYS;
struct myStruct {
    u32 type;
    union {
        u32 value; 
        char * str;
        void * data;
        MYS ** block;
        MYS * plug;
    };
    u32 state, msg,  count, index;
};
int main(int argc, char *argv[]){
    int i, j;
    MYS *ref;
    printf ("size of myStruct: %d\n\n", sizeof(MYS));
    for(i=0; i < 10; i ++){
        printf("allocating started...\n");
        for (j = 0; j < 1000000 ; j ++){
            ref = (MYS *) malloc(sizeof(MYS));
            assert(ref);
            memset(ref, 0, sizeof(MYS));
        }
        printf("   Done... Press 'enter' for Next Batch\n");
        _getch();
    }
    _getch();
    return 0;
}

和一个图像,显示一个循环后我的机器上的内存。每隔一次运行,就会增加~48MB而不是24MB!

process info after 1 loop (should be ~24MB)

2 个答案:

答案 0 :(得分:3)

这可能是由于填充,内部管家结构和内存对齐限制的结合。

当您调用malloc(size)时,实际上并没有获得size个字节的缓冲区。你得到一个至少 size字节的缓冲区。这是因为,出于效率原因,您的操作系统更喜欢只使用几种不同大小的内存缓冲区,并且不会定制缓冲区以节省空间。例如,你在Mac OS上要求24字节,你将获得32字节的缓冲区(浪费25%)。

将操作系统用于管理malloc ed缓冲区的结构添加到该分配开销中(可能会占每个分配的额外字节数),并且填充可能会增加对象的大小(到多个您的编译器的首选对齐方式),您将看到将数百万个小对象分配到单个缓冲区是非常昂贵的。

长话短说:只分配sizeof (YourType) * 1000000的一个大缓冲区,你不应该看到任何明显的开销。分配了一百万个sizeof (YourType)个对象,最终会浪费大量空间。

答案 1 :(得分:0)

malloc不是Windows上的OS服务,它由您的编译器实现。它可能有自己的分配策略,如另一个答案所示,它通常建立在HeapAlloc之上,它有一些自己的开销。

如果您想分配特定数量的网页,请致电VirtualAlloc