C语言中的结构上的free()问题。它不会减少内存使用量

时间:2011-05-14 23:05:16

标签: c memory-management struct malloc free

我的C程序中的struct上遇到free()问题。当我在free之前和之后查看/ proc // statm时它似乎没有减少。我在这种情况下使用free()错误,还是我读/ proc // statm错了?

这是一个产生问题的测试用例:

struct mystruct {
    unsigned int arr[10000];
};

void mem() {
    char buf[30];
    snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
    FILE* pf = fopen(buf, "r");
    if (pf) {
        unsigned size; //       total program size
        unsigned resident;//   resident set size
        unsigned share;//      shared pages
        unsigned text;//       text (code)
        unsigned lib;//        library
        unsigned data;//       data/stack
        unsigned dt;//         dirty pages (unused in Linux 2.6)
        fscanf(pf, "%u %u %u %u %u %u", &size, &resident, &share, &text, &lib,         &data);
        printf("Memory usage: Data = %d\n", data*sysconf(_SC_PAGESIZE));
    }
    fclose(pf);
}

int main(int argc, char **argv) {
    mem();
    struct mystruct *foo = (struct mystruct *)malloc(sizeof(struct mystruct));
    mem();
    free(foo);
    mem();
}

输出结果为:

Memory usage: Data = 278528
Memory usage: Data = 282624
Memory usage: Data = 282624

我希望它是:

Memory usage: Data = 278528
Memory usage: Data = 282624
Memory usage: Data = 278528

我用malloc'ing a(char *)进行了类似的测试,然后将其释放并且工作正常。结构有什么特别之处吗?

4 个答案:

答案 0 :(得分:12)

您的答案是right over here on Stack Overflow,但简短的版本是,由于很好的理由,内存分配器不会将内存返回给主机操作系统,而是将其保留(在程序的数据空间内部)作为空闲列表某种。

库保留内存的一些原因是:

  • 与内核交互比简单执行库代码要慢得多
  • 好处很小。大多数程序都具有稳定状态或增加的内存占用,因此分析堆查找可返回内存所花费的时间将被完全浪费。
  • 内部碎片使得页面对齐的块(唯一可以返回到内核的块)不太可能存在,另一个原因是不能减慢程序的速度以寻找不存在的东西
  • 返回嵌入在空闲块中的页面将分割页面两侧的块的低部分和高部分。
  • 少数返回大量内存的程序可能会绕过malloc()并使用mmap(2)分配和免费页面。

答案 1 :(得分:1)

每当free实际释放时,内存都依赖于实现。因此,当free在内存中占很大比例时,struct可能不会立即返回内存。我认为它与{{1}}没有任何关系。

答案 2 :(得分:1)

主要出于性能原因,分配的堆内存在释放后不会返回给操作系统。它将被标记为免费,也许稍后内核会将其恢复,或者您的程序将分配它并再次使用它。

我不知道你曾经分配/释放你的(char *)。你看到的差异可能是你的(char *)被分配在堆栈上,而它的发布/免费进程与堆不同(堆栈内存管理要简单得多)。

答案 3 :(得分:0)

操作系统可以真正释放您的数据,从而缩减程序的内存消耗。你只告诉它,你不再使用那个记忆了。