Бьерн Страуструп - Язык программирования С++. Главы 11-13
Страница 57. Управление памятью



13.10 Управление памятью

При проектировании библиотеки или просто программы с большим временем
счета один из ключевых вопросов связан с управлением памятью.
В общем случае создатель библиотеки не знает, в каком окружении она
будет работать. Будет ли там ресурс памяти настолько критичен, что ее
нехватка станет серьезной проблемой, или же серьезной помехой станут
накладные расходы, связанные с управлением памятью?
   Один из  основных вопросов управления памятью можно сформулировать
так: если функция f() передает или возвращает указатель на объект, то
кто должен уничтожать этот объект?  Необходимо ответить и на связанный
с ним вопрос: в какой момент объект может быть уничтожен? Ответы на эти
вопросы особенно важны для создателей и пользователей таких контейнеров,
как списки, массивы и ассоциативные массивы. С точки зрения
создателя библиотеки идеальными будут ответы: "Система" и "В тот момент,
когда объект больше никто не использует". Когда система уничтожает
объект, обычно говорят, что она занимается сборкой мусора, а та часть
системы, которая определяет, что объект больше никем не используется,
и уничтожает его, называется сборщиком мусора.
   К сожалению, использование сборщика мусора может повлечь за собой
накладные расходы на время счета и память, прерывания полезных
функций, определенную аппаратную поддержку, трудности связывания
частей программы на разных языках или просто усложнение системы.
Многие пользователи не могут позволить себе этого.Ь

Ь Говорят, что программисты на Лиспе знают, насколько важно управление
памятью, и поэтому не могут отдать его пользователю. Программисты
на С тоже знают, насколько важно управление памятью, и поэтому не
могут оставить его системе.

Поэтому в большинстве программ на С++ не приходится рассчитывать
на сборщик мусора и нужно предложить свою стратегию размещения
объектов в свободной памяти, не обращаясь к системе. Но реализации
С++ со сборщиком мусора все-таки существуют.
    Рассмотрим самую простую схему управления памятью для программ
на С++. Для этого заменим operator new() на тривиальную функцию
размещения, а operator delete() - на пустую функцию:

        inline size_t align(size_t s)
        /*
           Даже в простой функции размещения нужно
           выравнивание памяти, чтобы на объект
           можно было настроить указатель
           произвольного типа
        */
        {
          union Word { void* p; long double d; long l; }

          int x = s + sizeof(Word) - 1;
          x -= x%sizeof(Word);
          return x;
        }

        static void* freep; // настроим start на свободную память

        void* operator  new(size_t s) // простая линейная функция размещения
        {
          void* p = freep;
          s = align(s);
          freep += s;
          return p;
        }

        void operator delete(void*) { }  // пусто

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

 
« Предыдущая статья   Следующая статья »