Память кучи и выделение слябов

Я в замешательствеheap а такжеfree list, У меня есть несколько вопросов, и у меня есть собственное понимание того, как malloc работает на C. Пожалуйста, исправьте меня, если я ошибаюсь.

Is the heap memory organized as a linked list (free list) of data blocks ? Is there a difference between heap memory and free list ?

Мое понимание распределения памяти (открыто для улучшения): - Когда мы вызываем malloc, он выделяет память в куче и делает это, выбирая блок данных подходящего размера изfree list, право ?

Когда malloc возвращает определенный блок памяти, он удаляется из свободного списка, а физический адрес этого блока памяти обновляется в таблице страниц.

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

Таким образом, вся куча представляет собой свободный список (связанный список свободных блоков) + выделенные блоки данных.

Это исчерпывающая картина распределения памяти?

РЕДАКТИРОВАТЬ: Из Linux Kernel Development (Роберт Лав) Глава по управлению памятью,Slab allocation

"A free list contains a block of available, already allocated, data structures. When code requires a new instance of a data structure, it can grab one of the structures off the free list rather than allocate the sufficient amount of memory and set it up for the data structure. Later, when the data structure is no longer needed, it is returned to the free list instead of deallocated. In this sense, the free list acts as an object cache, caching a frequently used type of object."

Свободный список упоминается как «блок доступной распределенной структуры данных».

How is it allocated, when it is in a free-list ? And how is returning a block of memory to free list _not_ the same as deallocating that block ? How is slab allocation different from storage allocation

Ответы на вопрос(3)

что вы хотите сделать, это провести различие между распределением ядра и программы. Как сказал @Wyzard, malloc использует brk (sbrk и иногда mmap) для получения большего количества страниц из ядра. Мое понимание malloc не очень хорошее, но оно отслеживает то, что вы могли бы назвать ареной. Он обеспечивает доступ к памяти и выполняет надлежащие системные вызовы для выделения памяти по мере необходимости.

Свободный список является одним из способов управления памятью. Вызов mmap или brk каждый раз, когда вам нужно больше памяти из ядра, является медленным и неэффективным. Оба из них потребуют переключения контекста в режим ядра и будут распределять структуры данных, чтобы отслеживать, какой процесс владеет памятью. Свободный список на уровне пользователя - это оптимизация, позволяющая не постоянно запрашивать и возвращать память ядру. Цель пользовательской программы - выполнять свою работу, а не ждать, пока ядро выполнит свою работу.

Теперь, чтобы ответить на ваши другие вопросы:

How is it allocated, when it is in a free-list?

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

And how is returning a block of memory to free list not the same as deallocating that block?

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

How is slab allocation different from storage allocation?

Это начинает получать какую-то другую область (с которой я не очень знаком). Распределитель slab - это один из способов, которым ядро управляет распределением памяти. Из того, что я видел, плита пытается сгруппировать распределения по разным размерам и имеет пул страниц для удовлетворения этих запросов. Я полагаю, что обычные архитектуры x86 позволят выделять непрерывную физическую память емкостью от двух байтов до 16 МБ (хотя я на 64-битной машине). Я полагаю, что на этом уровне есть некоторая концепция свободного списка, а также способы эффективного обновления или понижения размера выделения, чтобы учесть изменяющиеся потребности системы.

С другой стороны, распределение памяти похоже на то, что на жестком диске есть место. Я на самом деле не слышал этот термин, поэтому я могу только строить догадки.

Решение Вопроса

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

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

The kernel allocates pages to a process, making those pages unavailable for use by other processes. From the kernel's standpoint, the pages can be located anywhere and their locations are tracked by the page table, but from the process's standpoint, it's a contiguous virtual address space. The "program break" that brk() manipulates is the boundary between addresses that the kernel will let you access (because they correspond to allocated pages) and addresses that will cause a segmentation fault if you try to access them. malloc() allocates variable-sized portions of the program's data segment for use by the program. When there's not enough free space within the current size of the data segment, it uses brk() to get more pages from the kernel, making the data segment bigger. When it finds that some space at the end of the data segment is unused, it uses brk() to give the unused pages back to the kernel, making the data segment smaller.

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

Ваше описание того, как работает свободный список, звучит правильно для меня, хотя я не эксперт в том, как реализованы распределители памяти. Но цитата, которую вы опубликовали от Роберта Лава, звучит так, как будто речь идет о распределении памяти в ядре Linux, которое не связано с выделением памятиmalloc() в процессе пользовательского пространства. Такой бесплатный список, вероятно, работает по-другому.

 12 апр. 2012 г., 05:26
Шарат: Я думаю, что вы все обдумываете - извините!
 12 апр. 2012 г., 08:37
malloc также часто, и в основном, используяmmap системный вызов, чтобы спросить память для ядра, и использоватьmunmap выпустить это.sbrk меньше используется.
 Sharat Chandra12 апр. 2012 г., 04:14
Вы говорите: «malloc () выделяет части с переменным размером сегмента данных программы» , Разве это не куча, на которую вы ссылаетесь? Является ли куча частью сегмента данных? Я хотя они были разные ..
 12 апр. 2012 г., 05:39
(Каким-то образом время испортилось, когда я безуспешно пытался добавить это к предыдущему комментарию.) Вайзард: Я написалmalloc() реализация с отладочными хуками 20-лет назад. Я быстро узнал, что ты не хочешьbrk() память возвращается к ядру, когда у вас есть неиспользуемые данные в конце сегмента данных. Вы будете делать ненужные системные вызовы, если ваша программа работает в циклеmalloc()с последующей кучейfree()s. Конечно, сильные реализации операционной системыmalloc() может иметь оптимизацию для обработки таких случаев, как это.
 12 апр. 2012 г., 05:49
@AlexMeasday, вы также не хотите постоянно связывать много памяти, если программа выделяет много, а затем освобождает все. Вы, вероятно, не хотитеbrk() вниз каждый раз, когда пространство становится доступным в конце сегмента данных, но, возможно, когда количество высвобождаемого пространства достигает некоторого порогового процента от общего размера сегмента данных. (Точно так же, когда выbrk() вверх, вы, вероятно, спросите место, пропорциональное текущему размеру сегмента данных.)

Buddy system allocator, used for allocating pages to Zone, uses the free_list to store free pages, allocate them , after freeing , if possible combine them back to one bigger contiguous page size of higher order. Slab allocator which works on a already allocated, data structures like keme_cache,kmalloc calls.

обращатьсяПамять кучи в программировании на C для кучи.

Для программы c в пользовательском пространстве у нас есть куча памяти в call_stack, где происходит malloc. Это отмечено _break, который продвигается sbrk (), когда требуется больше памяти.

В ядре Linux каждый процесс имеет task_struct, который имеет свой собственный стек и указатель на список используемых им страниц.

Ваш ответ на вопрос