Странное поведение в функции ‘malloc_stats’

Я делаю некоторые тесты с функцией ‘malloc_stats’, и я видел странное поведение, которое я не понимаю. Тест очень прост, я занимаюсь тем, что выделяю память и печатаю ‘malloc_stats’ до выделения, после выделения и после освобождения памяти. Это код, который я использую:

int main(int argc, char *argv[])
{
char *alloc[MAX_ALLOCS];
if ( argc < 3 or strcmp(argv[1], "--help") == 0 ) {
cout << argv[0] << " num-blocks block-size [free-step [start-free [end-free]]]" << endl;
return 1;
}

int numBlocks = atoi(argv[1]);
size_t blockSize = atoi(argv[2]);
int freeStep = (argc > 3) ? atoi(argv[3]) : 1;
int freeBegin = (argc > 4) ? atoi(argv[4]) : 0;
int freeEnd = (argc > 5) ? atoi(argv[5]) : numBlocks;

cout << "============== Before allocating blocks ==============" << endl;
malloc_stats();

for (int j = 0; j < numBlocks; j++)
{
alloc[j] = (char*) malloc(blockSize);
if (alloc[j] == NULL) {
cout << "ERROR: malloc" << endl;
return 1;
}
}

cout << endl << "============== After allocating blocks ==============" << endl;
malloc_stats();

for (int j = freeBegin; j < freeEnd; j += freeStep) {
free(alloc[j]);
}

cout << endl << "============== After freeing blocks ==============" << endl;
malloc_stats();

return 1;
}

И это вывод, который я получаю:

./exe 1000 100 1
============== Before allocating blocks ==============
Arena 0:
system bytes     =     135168
in use bytes     =      74352
Total (incl. mmap):
system bytes     =     135168
in use bytes     =      74352
max mmap regions =          0
max mmap bytes   =          0

============== After allocating blocks ==============
Arena 0:
system bytes     =     270336
in use bytes     =     186352
Total (incl. mmap):
system bytes     =     270336
in use bytes     =     186352
max mmap regions =          0
max mmap bytes   =          0

============== After freeing blocks ==============
Arena 0:
system bytes     =     270336
in use bytes     =      75136
Total (incl. mmap):
system bytes     =     270336
in use bytes     =      75136
max mmap regions =          0
max mmap bytes   =          0

На этом этапе, если я сравниваю «используемые байты» до выделения и после освобождения, есть разница 784 байта.

Я не могу понять, что происходит, я предположил, что «используемые байты» должны быть одинаковыми … где эти байты?

Спасибо.

3

Решение

Короткий ответ

Это расхождение в количестве байтов связано с подкачкой, используемой операционными системами, и не является утечкой памяти. Когда вы выделяете размеры блоков, не кратные размеру страницы, часть выделенной дополнительной памяти не освобождается. Эта дополнительная память может позже использоваться распределителем, и не просочилась.

Длинный ответ

Если мы проверим страницу руководства malloc_stats Функция [1], мы видим, что общее количество байтов, потребляемых распределениями в использовании, получается uordblks поле структуры mallinfo [2], в документации которой сказано, что uordblks общее количество выделенных байтов Здесь выделение не обязательно означает, что вся эта память используется вами как программист приложения. Распределитель может выделять больше памяти, чем было запрошено для выравнивания, если это приводит к повышению производительности и эффективности.

Это проблема, описанная в вашем вопросе. Вы запускаете свою программу как

./exe 1000 100 1

где 1000 — это количество блоков, а 100 — размер блока. Поскольку размер 100 не кратен размеру страницы, используемому операционной системой, malloc будет выделять больше памяти, чем вы запрашиваете при каждом вызове.

В качестве быстрой проверки, чтобы увидеть, что это действительно так, мы можем выделить размеры блоков, которые равны размеру страницы нашей операционной системы. В дистрибутивах Linux размер страницы можно получить с помощью следующей команды оболочки:

getconf PAGE_SIZE

который возвращает 4096 по моему делу. Когда я запускаю вашу программу как

./exe 100 4096 1

В качестве вывода я получаю следующее: (обратите внимание, что используемые байты после завершения освобождения совпадают с используемыми байтами до выделения)

============== Before allocating blocks ==============
Arena 0:
system bytes     =     135168
in use bytes     =      74352
Total (incl. mmap):
system bytes     =     135168
in use bytes     =      74352
max mmap regions =          0
max mmap bytes   =          0

============== After allocating blocks ==============
Arena 0:
system bytes     =     540672
in use bytes     =     485552
Total (incl. mmap):
system bytes     =     540672
in use bytes     =     485552
max mmap regions =          0
max mmap bytes   =          0

============== After freeing blocks ==============
Arena 0:
system bytes     =     208896
in use bytes     =      74352
Total (incl. mmap):
system bytes     =     208896
in use bytes     =      74352
max mmap regions =          0
max mmap bytes   =          0

Рекомендации

3

Другие решения

Других решений пока нет …

Похожие вопросы
Добавить ответ
Для оформления сообщений Вы можете использовать следующие тэги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Нажимая кнопку «Отправить», я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности этого сайта.