1

我想明白为什么数据动态分配被多次使用比代码直接指定或与malloc单个呼叫分配一个这么多的内存。内存分配和进程的内存使用

实例

作为实例,我提出了以下两个代码,在C:

test1.c:INT x被与malloc

int main (void) 
{ 
    int *x; 
    int i, n=1048576; //n=1024*1024; 

    printf("size = %lu\n", n* sizeof(int)); 

    for(i=0; i<n; i++) 
    { 
     x = malloc(sizeof(int)); 
     *x=i; 
    } 
    printf("Look at top and then press something to finish.");fflush(stdout); 
    getc(stdin); 
    return 0; 
} 

分配我没有使用免费在这里保持简单。 当程序正在等待的互动,我期待在另一个终端上的功能,它显示了我:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND          
1384 root 20 0 41300 34076 1300 S 0.0 3.3 0:00.47 test1 

test2.c中:INT X不是动态分配

int main (void) 
{ 
    int x[1048576]; //x[1024*1024] 
    int i, n=1048576; 

    printf("size = %lu\n", n* sizeof(int)); 

    for(i=0; i<n; i++) 
    { 
     x[i]=i; 
    } 
    printf("Look at top and then press something to finish.");fflush(stdout); 
    getc(stdin); 
    return 0; 
} 

和顶级显示我:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND          
1352 root 20 0 12404 5500 1304 S 0.0 0.5 0:00.05 test2 

我也做了一个第三码,也有相同的结果是test2的,在这里我使用:

x = malloc(n*sizeof(int)); 
for(i=0; i<n; i++) 
    { 
     x[i]=i; 
    } 

为什么在内存使用过程中有这么多差异?这是因为malloc请求新的内存页面,并有内存被浪费?或malloc分配更多的内存?

test1使用3.3%的总内存和test2使用0.5%

环境:

我执行这些测试在CentOS 5 64位内部搬运工。在虚拟环境

内存:

$ free -m 
       total  used  free  shared buff/cache available 
Mem:   995   98   845   3   51   808 
Swap:   1162   194   967 
+1

[Malloc vs自定义分配器可能重复:Malloc有很多开销。为什么?](http://stackoverflow.com/questions/13064850/malloc-vs-custom-allocator-malloc-has-a-lot-of-overhead-why) –

+0

看看这个答案: http:///stackoverflow.com/questions/10540845/linux-heap-structure-and-the-behaviour-with-malloc-and-free – JurekM

+0

这与'malloc vs自定义分配器'有关,但不完全相同。 –

回答

4

每一个内存分配必须被追踪,以便free()可以释放的空间再利用。实际上,这意味着有一个最小的内存大小被分配;它对于32位程序可以是8或16字节,对于64位程序可以是16-32字节(这取决于系统和正在使用的C库的版本)。

当你分别分配一百万个整数时,它们中的每一个都使用8-32个字节,所以你实际上已经使用了8-32MB的内存。当你在堆栈中的一个数组中分配一百万个整数时,你使用的是4MB的内存。

因此,您会发现进程大小存在实质性差异。

当然,第一个程序几乎泄漏了所有的内存,但这与您所问的问题是相切的。

+1

Jonathan很好的答案!但是,请注意,可能不需要最后一句,因为OP提到他为了简单而故意不包含'free()'。 :) – gsamaras

+1

是的;我的最后一句话不是100%必要的,但它也不是有害的。通过摆脱“免费”而获得的简单性非常重要;代码将需要“一百万”指针来存储百万分配的整数,增加了内存开销(需要4或8个MiB)。 –

2

系统需要每一个用户请求一些内存时间做一些家政服务。只需调用free就可以了,只要您的指针足以让系统取消分配内存。

所以,在你的第一个例子,你请求的内存n倍,而在第二只有一次。你打算使用的内存是相同的,但系统必须“记住”的信息不是。