Типичные реализации malloc
используют brk
/ sbrk
в качестве основного средства получения памяти от ОС. Однако они также используют mmap
для получения фрагментов для больших выделений. Есть ли реальная польза от использования brk
вместо mmap
или это просто традиция? Разве это не сработало бы так же хорошо, если бы все это делалось с mmap
?
(Примечание: здесь я использую sbrk
и brk
взаимозаменяемо, потому что они являются интерфейсами для одного и того же системного вызова Linux, brk
.)
Для справки, вот пара документов, описывающих glibc malloc:
Справочное руководство по библиотеке GNU C: Распределитель GNU
https://www.gnu.org/software/libc/manual/html_node/The-GNU-Allocator.html
glibc wiki: Обзор Malloc
https://sourceware.org/glibc/wiki/MallocInternals
То, что описывают эти документы, это то, что sbrk
используется, чтобы требовать первичной арены для небольших распределений, mmap
используется, чтобы требовать вторичных арен, и mmap
также используется, чтобы требовать места для больших объектов («гораздо больше»). чем страница ").
Использование как кучи приложения (заявлено с sbrk
), так и mmap
вносит дополнительную сложность, которая может быть ненужной:
Allocated Arena - основная арена использует кучу приложения. Другие арены используют кучи mmap'd. Чтобы отобразить кусок в кучу, вам нужно знать, какой случай применим. Если этот бит равен 0, фрагмент поступает с главной арены и основной кучи. Если этот бит равен 1, порция поступает из памяти mmap, и местоположение кучи может быть вычислено из адреса порции.
[Glibc malloc получен из ptmalloc, который был получен из dlmalloc , который был запущен в 1987 году.]
Справочная страница jemalloc (http://jemalloc.net/jemalloc.3.html) говорит следующее:
Традиционно, распределители использовали sbrk (2) для получения памяти, которая является неоптимальной по нескольким причинам, включая условия гонки, повышенную фрагментацию и искусственные ограничения на максимальное использование памяти. Если sbrk (2) поддерживается операционной системой, этот распределитель использует как mmap (2), так и sbrk (2) в указанном порядке предпочтения; в противном случае используется только mmap (2).
Итак, они даже говорят здесь, что sbrk
является неоптимальным, но они все равно его используют, даже если они уже столкнулись с проблемой написания своего кода, чтобы он работал без него.
[Написание jemalloc началось в 2005 году.]
ОБНОВЛЕНИЕ: Думая об этом больше, этот бит о «в порядке предпочтения» дает мне строку запроса. Почему порядок предпочтений? Они просто используют sbrk
в качестве запасного варианта в случае, если mmap
не поддерживается (или не имеет необходимых функций), или возможно, чтобы процесс перешел в состояние, в котором он может использовать sbrk
, но не mmap
? Я посмотрю на их код и посмотрю, смогу ли я выяснить, что он делает.
Я спрашиваю, потому что я внедряю систему сборки мусора в C, и до сих пор не вижу причин использовать что-либо кроме mmap
. Мне интересно, есть ли что-то, чего я пропускаю.
(В моем случае у меня есть еще одна причина избегать brk
, которая заключается в том, что в какой-то момент мне может понадобиться malloc
)