做一些分析(mem&speed)我一直被win7分配的内存是我要求的两倍这一事实所困扰…注意,这是我第一次在win7上进行这种活动分析,所以我真的不知道会发生什么。
在win7(64位)下,我正在使用msvc的一个快速版本在一个循环中分配精确数量的ram。应用程序在32位中编译和运行。
我分配了24mb ram,任务管理器显示我的应用程序使用48mb(在所有内存列下,包括committed,因为我实际上是在新区域内进行memcopy)。当我得到24个(现在应该是48MB),我的应用程序跳到96,等等。
它们被分配为1000000个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!

最佳答案

这可能是由于填充、内部内务处理结构和内存对齐限制的组合。
当调用malloc(size)时,实际上不会得到size字节的缓冲区。您得到的缓冲区至少为size字节。这是因为,出于效率的原因,您的操作系统倾向于只使用两种不同大小的内存缓冲区,而不会为节省空间而定制缓冲区。例如,如果你在mac os上要求24个字节,你会得到32个字节的缓冲区(浪费25%)。
再加上你的操作系统用来管理malloced缓冲区的结构的分配开销(每次分配可能会占用一些额外的字节),以及填充可能会增加对象的大小(增加到编译器首选对齐方式的倍数)。您将看到,将数百万个小对象分配到单个缓冲区中是非常昂贵的。
长话短说:只分配一个sizeof (YourType) * 1000000的大缓冲区,您不应该看到任何明显的开销。分配一百万个sizeof (YourType)对象,最终会浪费大量空间。

07-28 03:06
查看更多