精神错乱是免费的()

时间:2011-09-22 22:38:52

标签: c dynamic malloc free structure

在我的简单C程序(gnu linux)中,我从proc / stat获取rss值 int GetRSS()从我的进程的proc / stat返回RSS值。


在这种情况下:

printf("A RSS=%i\n", GetRSS());
char *cStr = null;
cStr = malloc(999999);
if (cStr != NULL)
{
    printf("B RSS=%i\n", GetRSS());
    free(cStr);
    printf("C RSS=%i\n", GetRSS());
}

我明白了:

A RSS=980
B RSS=984
C RSS=980

我无法解释为什么C没有返回984


如果我两次运行相同的程序,我会得到:

A RSS=980
B RSS=984
C RSS=980
B RSS=984
C RSS=980

看起来很好。


但是,在这个例子中:

struct _test
{
    char *pChar;
}
struct _test **test_ptr;

int i = 0;
printf("D RSS=%i\n",GetRSS());
assert(test_ptr = (struct _test **)malloc( (10000) * sizeof(struct _test *)));

for (i = 0; i < 1000; i++)
{
    assert(test_ptr[i] = (struct _test *)malloc(sizeof(struct _test)));
    test_ptr[i]->pChar=strdup("Some garbage");
}

printf("E RSS=%i\n", GetRSS());

for (i=0; i<1000; i++)
{
    free(test_ptr[i]->pChar);
    free(test_ptr[i]);
}

free(test_ptr);
printf("F RSS=%i\n", GetRSS());

我明白了:

D RSS=980
E RSS=1024
F RSS=1024
D RSS=1024
E RSS=1024
F RSS=1024

咦?为什么记忆不能在这里释放?

3 个答案:

答案 0 :(得分:5)

已释放内存块的事实必然使该块最适合后续分配。内存管理器有几种策略可以选择一块内存(最合适,最差,最适合)。

大多数内存管理器也试图合并空闲块,但是有些人试图让空闲块在合并之前尽可能地“老化”,理论上随着它们的老化,它们旁边的块也会更好。被释放,提高合并块的成功率(从而减少碎片)。

该块未用于满足您的下一个分配请求的事实意味着它未被释放。

答案 1 :(得分:2)

free()手册页:“偶尔,free实际上可以将内存返回给操作系统并使进程变小。通常,它所能做的只是允许稍后调用malloc来重用该空间。与此同时,空间仍然在程序中,作为malloc内部使用的自由列表的一部分。“

答案 2 :(得分:1)

您的malloc图书馆选择不这样做。这可能是出于战略原因(为了避免以后必须转到系统以获得更多内存),或者可能是由于限制(在特定原因中,它无法识别它可以释放内存)。

一般来说,没关系。地址空间和虚拟内存通常不被视为稀缺资源。因此,尽量减少消费的过度努力通常是毫无价值的,而且往往是有害的。