Про память.
Четверг, Июль 3rd, 2008Помните, я уже писал о работе с памятью. Там было теоретически.
Сейчас столкнулся с инетересным (тоже теоретически. практически - убил бы) строением пулов. Двунаправленые.
Коротко, имеется два варианта.
1. Есть две разные структуры данных одинакового размера (например 32 байта). Выделенная память отдается обоим. При этом первая получает стартовый адрес в пуле и продвигается ++. Вторая получается самый низкий (т.е. адрес = конец пула - размер одного блока) адрес и продвигается –.
2. Во втором варианте структуры жанных разного размера.
Все. Память в пул никогда не возвращается, изначальной стартовой нарезки не происходит. Колличество элементов связано друг с другом логически, и примерно опредеяет работу по заниманию памяти.
При необходимости вернуть память обратно, т.е. объявить ее логически свободной, элементы добавляются в связные списки свободных блоков, которые используются тоже (реюзинг).
Минусы такой системы ясны невооруженным взглядом.
1. При нежесткой лигической связке или наличии разых условий связывания - размеры (точнее колличество элементов каждого типа данных) непредсказуемы.
2. Однажды полученый максимум одного из пары никогда не отдаст своих (даже равных по размеру) блоков своему партнеру по паре. Т.е. имея свободную память мы не сможем ее аллоцировать, и при этом (см. п.1) размеры непредсказуемы и зависят от внешних условий.
3. При разных размеров блоков (если они еще и не кратны) возможны небольшие потери свободного места памяти посредине при максимальной выборке.
4. В коде постоянные проверки на наличие вободных модулей в списках для реюзинга.
И много других мелочей, как неявное определение необходимых размеров пулов, свободных остатков.
Плюсов практически не нашел.
В алгоритме отсутствует даже намек, что при равных размерах блоков можно было бы динамически перераспределять свободные блоки между разными по смыслу.
Для этого ничего сложного было бы не нужно, достаточно вместо двух связных списков использовать один. Тогда можно было оправдать такую нестартовую нарезку, в случае дефицита на память в эмбедед системах. Но ее нет. Да и для разноразмерных блоков это не подходит, а перестраивать даже кратные блоки не очень то удобно, при явном перемешивании адресов.
Кроме того нет даже отдельных интерфейсов для работы с такой организацией, все намертво встроено в сам код.
Никак не могу понять, зачем надо было так вот усложнять алгоритмы, когда вполне можно обойтись либо однократным рещзервированием памяти в стандартные связные списки, в списки типа LIFO как я писал раньше. Методов может и не много, но вполне достаточно. Плюсы их известны заранее.
П.С. Странные люди.
