Слабые ссылки в ABAP

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

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

Сборщик мусора в ABAP устроен таким образом, что освобождает объект из памяти тогда, когда на него нет ссылки, и если методы объекта не подписаны на события иного объекта, ссылка на который еще жива. Сам по себе он вызывается «периодически» средой исполнения, но может быть вызван и вручную через вызов метода:

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

Чтобы избежать подобных проблем, язык или среда программирования могут поддерживать так называемые слабые ссылки. Такие ссылки используются так же, как и обычные, но не влияют на сборку мусора, поскольку не учитываются механизмом подсчёта ссылок.

В ABAP слабую ссылку можно получить через класс CL_ABAP_WEAK_REFERENCE, делается это следующим образом:

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

1

Если перед получением объекта 999999 вызвать сборщик мусора вручную, весь кэш будет очищен (в автоматическом режиме отчищается по частям) и объект не будет восстановлен по слабой ссылке.

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

Чтобы весь кэш был доступен после заполнения можно расширить структуру кэша на сильную ссылку и чистить её отдельным методом после заполнения:

Как ранее уже упоминалось, объект будет удален тогда сборщиком мусора, когда на него нет сильной ссылки и методы этого объекта не указаны в качестве обработчика события объекта, который еще жив. Далее рассмотрим пример, где это проявляется:

Перейдя в отладчике в инструмент анализа памяти мы увидим следующую картину:

2

Как видно из картинки, объект памяти, ссылающийся на экземпляр класса b жив, несмотря на то, что был вызван сборщик мусора.

Добавив деактивацию подписки на событие, мы убедимся, что описанное ранее правило действительно работает и объект будет удален, если в нем нет подписки на события объекта класса «А»:

3