Сборка мусора и внешние вызовы
Сборка мусора и внешние вызовы
Хорошо спроектированная ОО-среда со сборкой мусора должна решать еще одну практическую проблему. Во многих случаях ОО-программы взаимодействуют с программами, написанными на не ОО-языках. В следующих лекциях будет рассмотрено, как лучше обеспечить такое взаимодействие. (См. "Взаимодействие с не ОО-программой", лекцию 13)
Если ПО включает вызовы подпрограмм, написанных на других языках (называемых далее внешними программами), возможно, этим подпрограммам необходимо будет передавать ссылки на объекты. Это потенциально опасно для управления памятью. Предположим, что внешняя подпрограмма имеет следующий вид (преобразованная в соответствии с синтаксисом языка внешней программы):
r (x: SOME_TYPE) is
do
...
a := x
...
end
где a сущность, сохраняющая значение между последовательными вызовами r. Например, а может быть глобальной или статической переменной в традиционных языках, или атрибутом класса в нашей ОО-нотации. Рассмотрим вызов r(y), где y связан с некоторым объектом О1. Возможно, что через некоторое время после вызова, О1 становится недостижимым в объектной части нашей программы, но ссылка на него (от сущности a) остается во внешней программе. Сборщик мусора может - и в конце концов должен - утилизировать О1, но в данном случае это неправильно.
Для таких ситуаций необходимы процедуры, вызываемые из внешней программы, которые защитят нужный объект от сборщика. Эти процедуры могут быть названы:
adopt (a) - усыновлять
wean (a) - отнимать от груди, отлучать
и должны быть частью интерфейса любой библиотеки, обеспечивающей взаимодействие ОО-программ и внешних программ. В следующем разделе описан подобный механизм для языка С. "Усыновление" объекта забирает его из области действия механизма утилизации; "отлучение" - возвращает возможность утилизации.
Передача объектов в не ОО-языки и удерживание ссылки на них внешней программой - дело рискованное. Но избежать этого возможно не всегда. Например, ОО-проект нуждается в специальном интерфейсе между ОО-языком и имеющейся системой управления БД. В этом случае, можно разрешить внешней программе сохранять информацию об объектах. Такие низкоуровневые манипуляции никогда не должны появляться в нормальном программном продукте. Они должны содержаться в обслуживающем классе, написанном с единственной целью - скрыть детали от остальной части программы и защитить ее от возможных неприятностей.