Разница между malloc и mmap

Я пытаюсь реализовать malloc в c, и мне нужно использовать mmap, но я до сих пор не понимаю, в чем разница между malloc и mmap (MAP_ANNON), оба они возвращают зону памяти, поэтому почему мы используем malloc вместо mmap, что разница между этим:

c = malloc(1000)

и этот :

c = mmap(NULL, 1000, PROT_READ | PROT_WRITE| MAP_ANON, -1, 0);

person Hakim ELmansouri    schedule 30.10.2020    source источник
comment
У вас есть какой-нибудь код, который мог бы объяснить лучше, чем это описание? mmap предназначен не для выделения памяти, а для отображаемых в память файлов. Я не знаю, почему это применимо здесь. Если вы хотите точно знать, что он делает, это хорошо, но на него легко ответить, прочитав документацию.   -  person tadman    schedule 31.10.2020
comment
Если мы использовали флаг MAP_ANON, нам не нужно использовать файл, поэтому mmap возвращает зону памяти, но malloc также возвращает зону памяти, в чем разница?   -  person Hakim ELmansouri    schedule 31.10.2020
comment
Я не уверен, почему это был бы лучший подход, а не просто выполнение необходимых низкоуровневых вызовов ОС, которые malloc делает внутри.   -  person tadman    schedule 31.10.2020
comment
@tadman mmap используется вместе с потенциально sbrk для реализации malloc, если я не ошибаюсь.   -  person Carcigenicate    schedule 31.10.2020
comment
@Carcigenicate Это действительно зависит от вашей операционной системы. Windows общеизвестно странна, а в не-POSIX еще больше странностей.   -  person tadman    schedule 31.10.2020
comment
Если вы собираетесь использовать это для извлечения блока памяти, я бы поработал над написанием вокруг него правильного распределителя вместо того, чтобы делать целую кучу маленьких вызовов mmap.   -  person tadman    schedule 31.10.2020
comment
Забавно, на самом деле я только начал проводить собственное исследование, чтобы написать свой собственный malloc клон, и у меня было то же впечатление, что и у ОП. Мой первоначальный план состоял в том, чтобы отобразить несколько страниц с помощью mmap, а затем найти способ управления памятью на этих страницах (что, по-видимому, и использует OpenBSD). Однако, почитав, sbrk кажется более распространенным методом, так как явно анонимные вызовы mmap даже не стандартны:   -  person Carcigenicate    schedule 31.10.2020
comment
В этом отношении анонимное отображение похоже на malloc и используется в некоторых реализациях malloc(3) для определенных распределений. Однако анонимные сопоставления не являются частью стандарта POSIX, хотя реализованы почти во всех операционных системах с помощью флагов MAP_ANONYMOUS и MAP_ANON.   -  person Carcigenicate    schedule 31.10.2020
comment
@Carcigenicate: в системах, в которых нет MAP_ANONYMOUS, вы можете получить тот же эффект, сопоставив /dev/zero. Это просто немного менее эффективно из-за дополнительных системных вызовов.   -  person Nate Eldredge    schedule 31.10.2020


Ответы (1)


По аналогии, в системах, которые его поддерживают, mmap() поставляет память оптом, а malloc() поставляет ее в розницу. Поскольку в стандарте C указана только последняя функция, код, использующий mmap(), будет работать только с системами, которые его поддерживают (Unix определяет его, но не поддерживает некоторые другие операционные системы).

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

Если malloc() обнаружит, что ни одна из известных ей областей свободного хранилища не сможет удовлетворить запрос, она запросит область хранения из базовой среды (вероятно, используя mmap() в системе Unix или другие средства в системе Unix). другие системы), запишите его адрес для возврата вызывающему абоненту и добавьте любую часть региона, выходящую за рамки того, что необходимо немедленно, в список свободных регионов.

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

person supercat    schedule 30.10.2020
comment
Итак, как я понимаю: Malloc использует память, которая уже известна, и если этого недостаточно, он использует mmap, чтобы получить больше места, и причина, по которой мы не используем mmap, заключается в том, что mmap всегда запрашивает новое пространство памяти, не проверяя, есть ли уже отображенное в памяти есть свободное место Я прав? - person Hakim ELmansouri; 31.10.2020
comment
@HakimELmansouri: многие операционные системы предназначены для работы с фрагментами, кратными 4 КБ или 64 КБ хранилища. Если бы кто-то захотел использовать функцию распределения ОС для создания 500 объектов, каждый из которых имел бы длину 64 байта, эти 500 объектов могли бы занять 2 048 000 байт памяти. Напротив, в зависимости от того, как malloc() отслеживает ситуацию, выделение может занимать всего 32 000 байт и, скорее всего, не более 48 000. - person supercat; 31.10.2020