безумие бесплатно () - PullRequest
       39

безумие бесплатно ()

5 голосов
/ 23 сентября 2011

В моей простой программе на C (gnu linux) я получаю значение rss из proc / stat.
int GetRSS() возвращает значение RSS из proc / stat для моего процесса.


В этом случае:

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 ]

5 голосов
/ 23 сентября 2011

Тот факт, что блок памяти был освобожден, не обязательно делает этот блок наиболее подходящим для последующего выделения. У менеджера памяти есть несколько стратегий выбора блока памяти (наилучшее соответствие, худшее соответствие, первое соответствие).

Большинство менеджеров памяти также пытаются объединить свободные блоки, но некоторые стараются, чтобы свободные блоки "стареют" как можно дольше, прежде чем объединяться, исходя из теории, что с возрастом существует больше шансов, что блоки рядом с ними быть освобожденным, улучшая уровень успеха в объединяющихся блоках (таким образом уменьшая фрагментацию).

Тот факт, что блок не использовался для удовлетворения вашего следующего запроса на выделение, не означает, что он не был освобожден.

2 голосов
/ 23 сентября 2011

На справочной странице free(): «Иногда free фактически может вернуть память операционной системе и уменьшить объем процесса. Обычно все, что он может сделать, это разрешить последующему вызову malloc повторно использовать пространство. Тем временем , пространство остается в вашей программе как часть свободного списка, используемого внутри malloc. "

1 голос
/ 23 сентября 2011

Ваша библиотека malloc решила не делать этого.Это может быть по стратегическим причинам (чтобы избежать необходимости обращаться к системе за дополнительной памятью позже) или из-за ограничений (в этом конкретном случае он не осознает, что может освободить память).1002 * В общем, это не имеет значения.Адресное пространство и виртуальная память обычно не считаются дефицитными ресурсами.Поэтому чрезмерные усилия по минимизации их потребления, как правило, бесполезны в лучшем случае и часто вредны.

...