Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГЭ-2013-анн-130515.doc
Скачиваний:
5
Добавлен:
01.05.2025
Размер:
1.69 Mб
Скачать

8.2. Методы динамического распределения памяти, основанные на списках блоков переменной длины

Потери на внутреннюю фрагментацию еще более заметны, если разброс длин блоков велик. Для её уменьшения лучше выделять блоки того размера, который затребован. Алгоритм распределения памяти в этом случае может быть аналогичным предыдущему, но, помимо признака «свободен-занят», блок должен хранить информацию о размере. Однако такой алгоритм при своей простоте довольно расточителен из-за частого сбора мусора. Поэтому чаще применяют другие алгоритмы, в основе которых лежит представление свободной памяти в виде списочной структуры.

Представим себе, что свободная память организована как линейный однонаправленный список, каждое звено которого содержит, помимо собственно области памяти, ее размер n и ссылку на следующее звено. Первоначально список состоит из единственного звена. При выделении необходимого размера памяти m, если m<n, от звена отделяется необходимый блок и передается заказчику, а размер оставшейся памяти в звене корректируется (n:=n-m). Если требуемый размер памяти совпадает с тем, что есть в звене (m=n), всё звено целиком исключается из списка свободных. Если какой-то блок памяти освободился, его включают в список свободных.

Разумеется, реально алгоритм сложнее. Очевидно, если блок возвращается в список свободных, полезно выяснить, свободны ли смежные с ним блоки. Если это так, целесообразнее объединить новый блок со смежным звеном. Если свободны оба соседа, они вместе с блоком объединяются в одно звено. Заметим, речь идет не о соседстве в смысле ссылок, а о смежности по памяти! Чтобы было проще определить смежность блоков, следует поддерживать упорядоченность звеньев списка по возрастанию или убыванию их адресов. А для быстрого определения правого и левого соседа необходим двунаправленный список.

При длительной работе подобной процедуры распределения памяти возникает неприятный эффект: так как поиск свободного места производится с начала списка, там образуется большое количество мелких «обрезков» памяти, которые, чаще всего, не нужны. То есть со временем распределение памяти происходит медленнее. Значит, лучше работать не с линейным, а с кольцевым списком, и поиск блока производить с текущего места.

Рассмотрим дисциплину поиска подходящего звена. Различают два основных метода: «первый подходящий» и «наиболее подходящий». В первом случае считают подходящим первое попавшееся звено такое, что mn. Во втором случае требуется найти звено с минимальным n таким, что mn. Если есть «точный» блок (m=n), на этом поиск и закончится. Но чаще этого не происходит, приходится просматривать весь список, что займет определенное время. Для его сокращения Кнут [1-Кнут] советует упорядочить список по возрастанию (убыванию) длин звеньев списка. Но это, как мы знаем, ухудшит алгоритм обнаружения смежных участков памяти. В результате работы по алгоритму «наиболее подходящий» в памяти образуется множество очень мелких участков, непригодных для использования, но требующих времени для их обработки. Для уменьшения их количества лучше не оставлять их в списке свободной памяти, а резервировать весь блок при малой величине n-m. Появляющаяся внутренняя фрагментация компенсируется возросшей скоростью. Если задать размер области k, которым можно пренебречь, поиск наиболее подходящего завершается при первом выполнении условия (n-m) k.

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

Эффективность различных методов распределения памяти зависит от распределения размеров требуемых блоков, частоты их запроса и освобождения, времени существования занятых блоков. Анализ этих методов сложен. Если времена жизни блоков примерно одинаковы, дисциплина их обслуживания похожа на очередь, если разброс времен велик, причем, большую долю составляют «маложивущие» блоки, дисциплина похожа на стек. Таким образом, однозначного способа распределения памяти нет.