C 内存分配和进程内存使用

C 内存分配和进程内存使用,c,memory-management,malloc,dynamic-memory-allocation,static-memory-allocation,C,Memory Management,Malloc,Dynamic Memory Allocation,Static Memory Allocation,我想了解为什么多次调用动态分配的数据比直接在代码中指定的或通过调用malloc分配的数据占用的内存要多 例子 例如,我用C编写了以下两个代码: test1.c:intx与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
分配的数据占用的内存要多

例子 例如,我用C编写了以下两个代码:

test1.c:intx与
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;
}
test2.c:intx不是动态分配的

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;
}
我还编写了第三个代码,其结果与test2相同,我使用了:

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

每当用户请求一些内存时,系统需要进行一些整理。当仅使用指针调用free就足以让系统取消分配内存时,应该记住这一点


因此,在第一个示例中,您请求内存
n
次,而在第二个示例中仅请求一次。您打算使用的内存是相同的,但系统必须“记住”的信息不是

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

当您分别分配一百万个整数时,每个整数都使用8-32字节,因此实际上使用了8-32 MiB内存。当您在堆栈上的单个数组中分配一百万个整数时,您使用的是4MIB内存

因此,您会发现流程大小有很大差异


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

可能的重复看看这个答案:这与“malloc vs custom allocator”有关,但并不完全相同。这也与SO 1054085(Linux堆结构以及malloc和free的行为)有关,但不完全一样。(或者也许我今天只是异常挑剔-不确定。)注意test2是从堆栈中分配空间,这是在程序加载和启动时预先分配的。第三个示例从堆执行一次性分配,因此它应该比第二个示例使用更多内存。回到test2,一个4兆字节+的堆栈似乎异常大。我想知道智能编译器是否会检测到x[]是main的本地变量,并使用类似于静态的变量(来自程序内存而不是堆栈)。答案很好!但是,请注意,最后一句可能不需要,因为OP提到为了简单起见,他故意不包括
free()
。)对我的最后一句话不是百分之百必要的,但也没有害处。将
免费
排除在外所获得的简单性意义重大;代码需要“一百万”指针来存储分配的一百万个整数,这增加了内存开销(需要4或8个MiB)。
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 
x = malloc(n*sizeof(int));
for(i=0; i<n; i++)
    {
        x[i]=i;
    }
$ free -m
              total        used        free      shared  buff/cache   available
Mem:            995          98         845           3          51         808
Swap:          1162         194         967