Нужна ли поддержка Malloc OS? - PullRequest
0 голосов
/ 03 ноября 2018

Управление памятью - это сервис, предоставляемый базовой операционной системой. Когда мы вызываем malloc()/free() и не работает ни одна операционная система (например, встроенная система с «голым железом»), как происходит распределение памяти и отслеживание?

Должна существовать сущность, которая отслеживает, какие адреса свободны, а какие нет. Это блок управления памятью ОС. malloc()/free() будет затем вызывать системные вызовы ОС. Так что нет ОС значит нет malloc()/free(). Я ошибаюсь, предполагая это?

Обновление:

Во всех ответах указывалось, что malloc/free может использовать либо статическое распределение пула (когда ОС недоступна), либо использовать sbrk/brk, которые являются системными вызовами ядра. Вопрос в том, как malloc/free знает, есть ли ядро ​​под ним или нет?

Ответ (см. Комментарий «Куба Обер» под его ответом ниже):

malloc ничего не нужно знать, потому что библиотека C, с которой вы связываете свой проект, специфична для цели: если вы разрабатываете для Linux, вы используете библиотеку C для Linux, отличную от той, что вы разрабатываете для OS X или Windows, или голые кости ARM Cortex M0. Или, черт возьми, barebones x86. Люди, которые пишут библиотеку C, знают, как ее реализовать, чтобы она работала на желаемую цель. Например, библиотека barebones C для x86 будет использовать EFI и ACPI для запроса списка доступных блоков оперативной памяти, не используемых аппаратным обеспечением или BIOS, а затем использовать их при выполнении запросов на выделение.

Ответы [ 3 ]

0 голосов
/ 04 ноября 2018

Функция Malloc / free управляет пулом памяти. Эти функции обычно не являются службами операционной системы.

Как тогда создается этот пул?

В большинстве систем malloc вызывает службы операционной системы для отображения страниц в адресное пространство процесса, чтобы создать и расширить пул памяти. Если вы вызываете malloc, а память недоступна, большинство реализаций будет вызывать системную службу для отображения дополнительной памяти и расширения пула.

Реализация malloc должна поддерживать структуры данных, которые отслеживают, какая память в пуле свободна и какая была выделена. Это делается разными способами. Программисты нередко выбирают комбинацию malloc / free, которая лучше всего подходит для них, и вставляют ее в свое приложение.

Итак, да, операционная система задействована, как правило.

Но вы спрашивали о том, могут ли они быть реализованы без операционной системы.

Предположим, вы сделали:

   static char pool [POOLSIZE] ;

в вашей реализации malloc. Тогда вам не потребуется системная служба для создания пула во время выполнения. С другой стороны, ваш бассейн имеет фиксированный размер.

0 голосов
/ 04 ноября 2018

Вообще говоря: нет или, по крайней мере, не во время выполнения, если мы определяем время выполнения как моменты между main() входом и выходом.

Предположим, вы внедрили malloc, который работает с пулом фиксированного размера:

static char pool[MALLOC_POOL_SIZE];

void *malloc(size_t size) {
  …
}

void free(void *block) {
  …
}

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

Таким образом, нет, как правило, не требуется участия ОС после запуска вашего кода, но участие ОС необходимо для того, чтобы ваш код работал в первую очередь (если есть ОС).

И, конечно, «не нужно» означает не нужно, но не исключает поддержку ОС для динамического выделения памяти в конкретной библиотеке времени выполнения Си. В большинстве размещенных сред выполнения malloc использует пул, который динамически расширяется (и, возможно, сокращается) путем вызова соответствующих API-интерфейсов ОС. В классическом Unix расширение будет осуществляться через системный вызов brk.

0 голосов
/ 03 ноября 2018

malloc() и free() не требуют поддержки ОС. Они могут быть (и часто!) Реализованы на голых металлических системах. Например, библиотека Arduino использует malloc() и free() для управления строками.

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

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

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

struct malloc_block {
    struct malloc_block *prev, *next;
    size_t size;
    ...
    char allocation[];
};

и возврат указателя на allocation в качестве возвращаемого значения malloc(). Такие функции, как realloc() и free(), могут извлекать структуру, вычитая размер структуры из указателя на распределение.

...