2016-01-31 1 views
0

Я обнаружил, что malloc() выделяет больше пространства памяти, чем я прошу.Почему malloc выделяет больше пространства памяти, чем я прошу?

struct { void *ptr; int var; } msg; // 16 bytes (checked by sizeof()) 

for (int i = 0; i < 100000000; i++) 
    malloc(sizeof(msg)); 

В качестве вышеупомянутого кода, на самом деле malloc() выделить 32 байт на вызов функции (рассчитанный top), но valgrind показывает только 16 байт на вызов на самом деле.

Почему malloc выделяет больше пространства памяти, чем я прошу, и как заставить malloc() не тратить столько пространства памяти?

Удивительно, что он выделяет 32 байта также, даже если структура равна 24 байтам, поэтому я предполагаю, что пространства памяти теряются. Я не уверен, должно ли malloc() выделить несколько 32 байтов. Если это правда, то пространство памяти пропадает.

EDITED:

Я проверил для других обстоятельств.

+---------+---------------------------+ 
| n | memory usage of malloc(n) | 
+---------+---------------------------+ 
| 1 ~ 24 |   32 bytes   | 
+---------+---------------------------+ 
| 25 ~ 40 |   48 bytes   | 
+---------+---------------------------+ 
| 41 ~ 56 |   64 bytes   | 
+---------+---------------------------+ 

Память не в полной мере, если используется n не 16 * m + 8, m ∈ ℕ. Некоторые пробелы в памяти понятны из-за выравнивания памяти, когда n равно 22, но по-прежнему следует считать впустую, когда n равно 16. На большинстве платформ размер минимального блока доступа к памяти составляет 4 байта или 8 байтов, поэтому почему GCC-реализация выбирает 16 байт на увеличение.

+2

Накладные расходы на выделение. 'malloc' нуждается в некоторой памяти для собственных структур данных. См., Например, [Malloc vs custom allocator: у Malloc много накладных расходов. Почему?] (Http://stackoverflow.com/questions/13064850/malloc-vs-custom-allocator-malloc-has-a-lot-of-overhead-why) – kaylum

+0

Удивительно, что он выделяет 32 байта ** также ** даже если структура составляет 24 байта, поэтому я предполагаю, что пространства памяти ** теряются **. –

+0

Почему вы говорите, что это напрасно? Отходы подразумевают стоимость без чего-либо взамен, что на самом деле не так. Это стоимость управления памятью определенным образом. – kaylum

ответ

1

Любая дополнительная память, если таковые имеются, выделенные malloc(), calloc() и т.д. является реализация определяется аспект системы и не определен С.

Проверьте спецификацию вашего компилятора, чтобы твердо почему. Обычно это для управления памятью.

Чтобы создать другую схему распределения, перепишите malloc() или используйте свои собственные функции выделения памяти.

1

malloc() имеет очень важное время выполнения накладные расходы. Библиотека GNU C использует ptmalloc, которая основана на dlmalloc («Doug Lea's Malloc»).

Память в куче выделяется как «куски», выравниваемая структура данных 8-byte, которая содержит заголовок и полезную память. Выделенная память содержит накладные расходы 8 или 16 byte для размера флагов куска и использования. Нераспределенные куски также хранят указатели на другие свободные куски в полезной космической области, делая минимальный размер куска 24 bytes.

Нераспределенная память сгруппирована в «бункеры» аналогичных размеров, реализованные с использованием двойного списка кусков (с указателями, хранящимися в нераспределенном пространстве внутри фрагмента).

Для запросов ниже 256 bytes (запрос «smallbin»), используется простой двухрежимный распределитель мощности. Если в этом ящике нет свободных блоков, блок из следующего старшего бина разбивается на два.

Вы можете прочитать больше об этом here

+0

Plus 1 для вашей большой информации, но это все еще не может уменьшить использование памяти в моем коде. –

0

Избыточные байт выделяется то есть накладные расходы конкретной реализации, менеджер памяти в реализации выделяет столько памяти, сколько необходимо для целей внутреннего слежения/дома по поддержанию. Объем памяти не считается потерянным. Ваша забота искренна, особенно если вы смотрите на миллионы небольших ассигнований - это приведет к обширной фрагментации памяти кучи и, конечно же, огромным накладным расходам. Поэтому я могу представить два варианта: напишите свой блок распределения кучи или лучше используйте диспетчер памяти, написанный/протестированный/разделяемый другими пользователями - начните с jemalloc Facebook или Google -

+0

Я отредактировал мой вопрос, чтобы объяснить причину, по которой я думаю, что пространство памяти считается потерянным. –