Ответ 1
Это на самом деле довольно неопределенный вопрос, и, вероятно, почему вы запутались. Имеет ли он в виду, что, учитывая существующую реализацию malloc, как вы собираетесь пытаться разработать более эффективный способ освободить базовую память? Или он ожидал, что вы начнете обсуждать различные варианты реализации malloc и их преимущества и проблемы? Он ожидал, что вы узнаете, как виртуальная память функционирует на архитектуре x86?
Кроме того, более эффективно, имеет ли он значение более эффективного пространства или более эффективного времени? Нужно ли детекционировать дефиницию free()? Должно ли оно вернуть как можно больше памяти в ОС, поскольку это в среде с низкой памятью и многозадачностью? Какие наши критерии здесь?
Трудно сказать, с чего начать с такого расплывчатого вопроса, кроме как начать задавать свои вопросы, чтобы получить разъяснения. В конце концов, чтобы создать свою свободную функцию, вам сначала нужно знать, как реализуется malloc. Скорее всего, вопрос в том, действительно ли вы знали о том, как реализовать malloc.
Если вы не знакомы с внутренними функциями управления памятью, самый простой способ начать с понимания того, как реализован malloc, - это сначала написать свой собственный.
Ознакомьтесь с этой статьей IBM DeveloperWorks под названием "Управление внутренней памятью" для начала.
Но прежде чем вы сможете написать свой собственный malloc/free, вам сначала понадобится выделить/освободить память. К сожалению, в ОС защищенного режима вы не можете напрямую обращаться к памяти на аппарате. Итак, как вы его получите?
Вы запрашиваете ОС для этого. Благодаря функциям виртуальной памяти x86 любой фрагмент оперативной памяти или своп-памяти может быть сопоставлен с адресом памяти операционной системой. То, что ваша программа видит как память, может быть физически фрагментировано по всей системе, но благодаря диспетчеру виртуальной памяти ядра все выглядит одинаково.
Ядро обычно предоставляет системные вызовы, которые позволяют вам отображать дополнительную память для вашего процесса. В более старой ОС UNIX обычно было brk/sbrk, чтобы увеличить память кучи на краю вашего процесса или уменьшить его, но многие системы также предоставляют mmap/munmap, чтобы просто отобразить большой блок памяти кучи. Это только после того, как вы имеют доступ к большому, смежно выглядящему блоку памяти, который вам нужен malloc/free для управления им.
Как только ваш процесс имеет доступную ему кучу памяти, все это касается разделения его на куски, причем каждый кусок содержит свою метаинформацию о его размере и позиции и независимо от того, выделен ли он или нет, а затем управление этими фрагментами. Простой список структур, каждый из которых содержит некоторые поля для метаинформации и большой массив байтов, может работать, и в этом случае malloc должен запускаться через список, пока не найдет достаточно большой нераспределенный кусок (или куски, которые он может комбинировать), и затем карту в большем объеме памяти, если он не может найти достаточно большой кусок. Как только вы найдете фрагмент, вы просто возвращаете указатель на данные. free() может затем использовать этот указатель для обратного обращения нескольких байтов к полям-членам, которые существуют в структуре, которые затем могут быть изменены (т.е. marking chunk.allocated = false;). Если в конце списка достаточно нераспределенных фрагментов, вы даже можете удалить их из списка и отменить или сжать эту память с вашей кучи процессов.
Это реальный простой способ реализации malloc. Как вы можете себе представить, существует множество возможных способов разделения вашей памяти на куски, а затем управление этими кусками. Там так много способов, как есть структуры данных и алгоритмы. Все они предназначены для разных целей, например, для ограничения фрагментации из-за небольших выделенных фрагментов, смешанных с небольшими, нераспределенными кусками, или обеспечения того, чтобы malloc и свободный бег быстро (а иногда даже медленнее, но предсказуемо медленно). Там dlmalloc, ptmalloc, jemalloc, Хранить malloc и многое другое, и многие из них довольно маленькие и кратки, поэтому не бойтесь их читать. Если я правильно помню, "Язык программирования C" Кернигана и Ричи даже использует простую реализацию malloc в качестве одного из своих примеров.