2011-07-11 16 views
6

做一些剖析(MEM &速度)两倍的RAM使用我一直跺着脚通过WIN7似乎确切地分配一倍RAM我问...请注意,这是第一个这样的事实我在win7上做了这样的主动分析,所以我不知道会发生什么。分配RAM显示在任务管理器

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

我分配的RAM 24 MB和任务管理器显示我的应用程序使用为48MB(所有内存栏下,包括承诺,因为我实际上是新的区域内memcopy'ing)。当我得到更多的24(现在应该是48MB),我的应用程序跳转到96等

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

我已经在网上搜索,但没有找到任何符合我的意见。

任何人都有线索?

如果这仅仅是挂羊头卖狗肉的操作系统(或无能?),没有任何工具,它可以给我一个进程的实际内存消耗? (它很难找到泄漏,当应用程序开始时;-)

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

注(通过在控制台标题栏中的路径)我建立在Release模式(使用所有默认的“空” 2010 MSVC的项目设置),所以被分配没有额外的“调试”内存(可在一些项目上相当广泛)。

这里是一个简短的,完整的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

你可以显示你分配内存的行吗? –

+6

你确定这个结构真的是24个字节吗?它可能会有一些对齐的情况发生。 – davin

+0

编辑过的问题...我在一个循环后添加了一个完整的代码示例,其中包含其他建筑细节和我的任务管理器的图片。希望这有助于:-) – moliad

回答

3

这可能是由于填充,内部持家结构和存储器对准限制的组合。

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

增加你的操作系统用于管理缓冲区的结构(可能会占用每个分配一些额外的字节),并且填充可能会增加对象的大小(对于编译器的倍数首选的对齐方式),你会发现将数百万个小对象分配到单独的缓冲区中非常昂贵。

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

+0

谢谢,所以我应该为这些结构实现我自己的(内存有效)池分配器?我将处理数以百万计的这些小结构。一次分配n个号码,然后在需要下一次分配之前保留多少号码(反之亦然)。 – moliad

+0

是的,如果你需要处理大量的小分配,你应该创建一个分配器,它使用'malloc'来一次保留大块内存。 – zneak

+0

顺便说一句,我做了很多测试,似乎我win7的所有malloc调用框添加额外的20-30字节(平均基于数百万不同大小的分配)。所以我猜系统的分配器本身是相当饿的(对于任何给定的分配,它都有很多值)。 – moliad

0

malloc不是Windows上的OS服务,它是由您的编译器实现的。它可能有自己的分配策略,如其他答案所示,它通常建立在HeapAlloc之上,它有自己的一些开销。如果要分配特定数量的页面,请致电VirtualAlloc

相关问题