Библиотека сайта rus-linux.net
Цилюрик О.И. Модули ядра Linux | ||
Назад | Внутренние механизмы ядра | Вперед |
Распределители памяти
Реально распределение памяти по запросам kmalloc() может поддерживаться различными механизмами более низкого уровня, называемыми распределителями. Совершенно не обязательно это будет выделение непосредственно из общей неразмеченной физической памяти, как может показаться — чаще это производится из пулов фиксированного размера, заранее размеченных специальным образом. Механизм распределителя памяти просто скрывает то, что скрыто «за фасадом» kmalloc(), те рутинные детали, которые стоят за выделением памяти. Кроме того, при развитии системы алгоритмы распределителя памяти могут быть заменены, но работа kmalloc(), на видимом потребителю уровне, останется неизменной.
Первоначальные менеджеры памяти использовали стратегию распределения, базирующуюся на heap («куча» - единое пространство для динамического выделения памяти). В этом методе большой блок памяти (heap ) используется для обеспечения памятью для любых целей. Когда пользователям требуется блок памяти, они запрашивают блок памяти требуемого размера. Менеджер heap проверяет доступную память и возвращает блок. Для поиска блока менеджер использует алгоритмы либо first-fit (первый встречающийся в heap блок, превышающий запрошенный размер), либо best-fit (блок в heap, вмещающий запрошенный размер с наименьшим превышением). Когда блок памяти больше не нужен, он возвращаются в heap. Основная проблема этой стратегии распределения — фрагментация, и деградация системы с течением длительного времени непрерывной эксплуатации (что особо актуально для серверов). Проблемой вторичного порядка малости является высокая затратность времени для управления свободным пространством heap.
Ещё один подход, применявшийся в Linux (называемый buddy memory allocation), выделяет по запросу блок, размером кратным степени 2, и превышающий фактический запрошенный размер (по существу, используется подход best-fit). При освобождении блока предпринимается попытка объединить в освобождаемый свободный блок все свободные соседние блоки (слить). Такой подход позволяет снизить фрагментирование и повышает эффективность управления свободным пространством. Но он может существенно увеличить непродуктивное расходование памяти.
Последний алгоритм распределителя, использующийся как основной в версиях ядра 2.6, это слаб алокатор (slab allocation). Слабовый распределитель впервые предложен Джефом Бонвиком (Jeff Bonwick), реализован и описан в SunOS (в середине 90-х годов). Идея такого распределителя состоит в том, что запросы на выделение памяти под объекты равного размера удовлетворяются из области одного кэша (слаба), а запросы на объекты другого размера (пусть отличающиеся от первого случая самым незначительным образом) - удовлетворяются из совершенно другого такого же кэша.
Примечание: Сам термин слаб переводится близко к «облицовочная плитка», и принцип очень похож: любую вынутую из плоскости плитку можно заменить другой такой же, потому, что их размеры в точности совпадают.
Использование слаб алокатора может быть отменено при сборке ядра (параметр CONFIG_SLAB). Это имеет смысл и используется для небольших и встроенных систем. При таком решении включается алокатор, который называют SLOB, он может экономить до 512KB памяти, но страдает названными уже недостатками, главный из которых - фрагментация. Дальше детально мы будем рассматривать только слабовый распределитель.
Предыдущий раздел: | Оглавление | Следующий раздел: |
Динамическое выделение участка | Слабовый распределитель |