【问题标题】:Some memory seems to be left allocated after malloc() and free()在 malloc() 和 free() 之后似乎分配了一些内存
【发布时间】:2010-12-16 16:16:12
【问题描述】:

我是 C 新手。我正在努力适应 malloc + free。我编写了以下测试代码,但由于某种原因,内存没有完全释放(顶部仍然表示分配给进程的内存约为 150MB)。这是为什么呢?

#include <stdio.h>
#include <malloc.h>

typedef struct {
    char *inner;
} structure;

int main()
{
    int i;
    structure** structureArray;

    structureArray = (structure**)malloc(sizeof(structure*)*1000*10000);
    for (i = 0; i < 1000*10000;i++)
    {
        structureArray[i] = (structure*) malloc(sizeof(structure));
        structureArray[i]->inner = (char*) malloc(sizeof(char)*1000*1000*1000);
    }

    printf("freeing memory");
    for (i = 0; i < 1000*10000;i++)
    {
        free(structureArray[i]->inner);
        free(structureArray[i]);
    }
    free(structureArray);

    system("sleep 100");
    return 0;
}

对应的 Makefile:

all: test.c
    gcc -o test test.c
    ./test &
    top -p `pidof ./test`
    killall ./test

【问题讨论】:

  • 您是否使用过挡泥板对其进行了测试?还是瓦尔格林?它们将为您提供更好的内存泄漏统计信息。
  • 你知道你要分配多少内存吗?
  • 谁在乎?这是一个 64 位系统——地址空间并不完全是稀缺资源。无论如何,系统从来没有给你对物理内存 (RAM) 的独占控制权。

标签: c++ c memory-management malloc free


【解决方案1】:

top 将告诉您分配给您的进程的物理内存量。虚拟内存是物理内存之上的抽象,malloc/free 在此之上提供了抽象。

malloc 从程序堆中保留空间。堆只是程序的虚拟地址空间用于临时存储的区域。当您更多地调用malloc 时,使用brk 系统调用扩展堆。但是,尽管堆的虚拟大小增加了,但在您读取或写入新分配的内存之前,并未实际分配物理内存。例如,由于您从不写入分配给记录的 inner 字段的内存,因此这些分配不会占用任何物理 RAM。

free 只是释放由malloc 分配的部分堆。这并不一定会减少堆的虚拟大小,因此与其关联的物理内存可能不会被释放。这就是为什么您没有看到物理内存使用量减少的原因。

【讨论】:

  • 谢谢,这个解释很全面。
【解决方案2】:

Unix 内存管理是惰性的,除非有人真的不需要它,否则不能保证释放进程内存。 Here is好文章。

另外我建议你检查 malloc() 结果,你肯定会发现其中至少有一些失败了。

【讨论】:

  • malloc 失败的原因是操作系统不再让您的进程分配内存。
【解决方案3】:

可能是由于您分配了 10000000000000000 字节 (1000*10000*1000*1000*1000) =~ 10000000000 Mbytes = 10000000 GB 的顺序,这会多次包裹您的系统内存。

【讨论】:

  • 如果 OP 在 64 位系统上,则不会。
  • 在 64 位 Linux 上,尽管分配了如此多的内存,但由于它使用了惰性分配器,您仍然可以摆脱它。几乎在其他任何地方,您很久以前就会失去(虚拟)内存。在 Linux 上,你会内存不足。我想对你投赞成票,但你需要表明它并不像“多次包装系统内存”那么简单。
  • 系统内存是指物理内存而不是虚拟内存。提问者似乎不太可能拥有具有 10000000 GB 物理内存的系统,因此该程序可能不是预期的。
猜你喜欢
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
  • 2019-10-31
  • 2014-07-17
  • 1970-01-01
  • 1970-01-01
  • 2014-02-15
  • 2010-10-25
相关资源
最近更新 更多