Даже если можно было бы избежать ошибочных вызовов reclaim, остается вопрос - сколь реально просить разработчиков управлять удалением объектов? Загвоздка в том, что даже при обнаружении объекта, подлежащего утилизации, обычно просто удалить его недостаточно, он может сам содержать ссылки на другие объекты и нужно решить, что с ними делать.

Рассмотрим структуру, показанную на рис.9.10, ту же, что использовалась в предыдущей лекции для описания динамической природы объектных структур. Допустим, выяснилось, что можно утилизировать самый верхний объект. Тогда в отсутствии каких-либо других ссылок можно удалить и другие два объекта, на один из которых он ссылается прямо, а на другой - косвенно. Не только можно, но и нужно: разве хорошо удалять только часть структуры? В терминологии Pascal это иногда называется рекурсивной проблемой удаления: если операции утилизации имеют смысл, они должны быть рекурсивно применены ко всей структуре данных, а не только к одному индивидуальному объекту. Но конечно, необходимо быть уверенным, что на объекты удаляемой структуры нет ссылок из внешних объектов. Это трудная и чреватая ошибками задача.

Рис. 9.10.  Прямые и косвенные взаимные ссылки

На этом рисунке все объекты одного типа PERSON1. Предположим, что сущность x присоединена к объекту О типа MY_TYPE , объявленным как класс:

class MY_TYPE feature

attr1: TYPE_1

attr2: TYPE_2

end

Каждый объект типа MY_TYPE, такой как О, содержит две ссылки, которые (кроме void) присоединены к объектам типа TYPE_1 и TYPE_2. Утилизация О может предполагать, что эти два объекта тоже должны быть утилизированы, также как и зависимые от них объекты. Выполнение рекурсивной утилизации, в этом случае, предполагает написание множества процедур утилизации, - по одной для каждого типа объектов, которые, в свою очередь, могут содержать ссылки на другие объекты. Результатом будет множество взаимно рекурсивных процедур большой сложности.

Все это ведет к катастрофе. Нередко, в языках, не поддерживающих автоматическую сборку мусора, в приложения включаются специально разработанные системы управления памятью. Такая ситуация неприемлема. Разработчик приложения должен иметь возможность сконцентрироваться на своей работе, а не стать счетоводом или сборщиком мусора.

Возрастающая сложность программы из-за ручного управления памятью приводит к падению качества. В частности, она затрудняет читаемость и такие свойства как простота обнаружения ошибок и легкость модификации. В результате, к сложности конструкции добавляется проблема надежности. Чем сложнее система, тем больше вероятность содержания ошибок. Дамоклов меч ошибочного вызова reclaim всегда висит над головой и, скорее всего, упадет в наихудшее время: когда система пройдет тестирование и начнет использоваться, создавая большие и замысловатые структуры объектов.

Вывод очевиден. Кроме жестко контролируемых ситуаций (рассмотренных в следующем разделе), ручное управление памятью не подходит для разработки серьезных систем, как минимум, по соображениям качества.

<p>Подход на уровне компонентов</p>

(Этот раздел описывает решение, полезное только для специального случая; его можно пропустить при первом чтении книги.)

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

Это решение применимо только для ОО-программирования "снизу-вверх", где структуры данных создаются не для нужд конкретной программы, а строятся как повторно используемые классы.

Что предлагает ОО-подход по отношению к управлению памятью? Одна из новинок скорее организационная, чем техническая: в этом подходе большое внимание уделяется повторному использованию библиотек. Между разработчиками приложения и создателями системных средств - компилятора и среды разработки - стоит третья группа людей, отвечающих за написание повторно используемых компонентов, реализующих основные структуры данных. Членов третьей группы, которые, конечно могут иногда выступать и в двух других ипостасях, принято называть производителями компонентов (component manufacturers).

Производители компонентов имеют полный контроль над любым использованием данного класса и потому находятся в лучшем положении при поиске приемлемого решения проблемы управления памятью для всех экземпляров этого класса.

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

<p>Управление памятью связного списка</p>
Перейти на страницу:

Похожие книги