Как реализовать слабые ссылки с Boehm GC? - PullRequest
1 голос
/ 01 мая 2019

У меня есть личный проект, который я реализую с помощью Boehm GC. Мне нужно реализовать своего рода тип события, который должен содержать ссылки на другие события. Но мне также нужно убедиться, что указанные события все еще доступны для сбора, поэтому мне нужны слабые ссылки для этого.

Допустим, у нас есть события A, B и C. Я настраиваю эти события, чтобы сигнализировать о событии X всякий раз, когда любое из них сигнализируется. Это означает, что A, B и C должны содержать ссылку на событие X. Я хочу, чтобы, если событие X недостижимо, событиям A, B и C больше не нужно было сигнализировать об этом. Таким образом, слабая ссылка - это то, о чем я думал.

Есть ли другой способ сделать это? Я не хочу менять GC, но при необходимости (интерфейс выделения остается чистым) я мог бы.

Проект написан на C. Если потребуется, я предоставлю больше информации. Примечательно, что если есть какой-либо способ реализовать такие события непосредственно с помощью этой семантики, то нет необходимости в реальных слабых ссылках (события МОГУТ иметь цикл ссылок, хотя они и не сигнализируются).

1 Ответ

3 голосов
/ 01 мая 2019

В Boehm GC отсутствует концепция слабых ссылок как таковая .Однако он не сканирует память, выделенную системой malloc, для ссылок на управляемые объекты, поэтому указатели, хранящиеся в такой памяти, не препятствуют сбору указанного объекта.Конечно, этот подход означает, что объекты, содержащие указатели, не будут управляться сборщиком.

В качестве альтернативы может быть возможно злоупотребление GC_MALLOC_ATOMIC() или GC_malloc_explicitly_typed() для получения управляемого объекта, который может содержать указателидругим управляемым объектам, не мешая другим объектам собираться.Это в основном сводится к тому, что GC указывает, являются ли некоторые элементы указателями, чтобы предотвратить их сканирование.

В любом случае, вам также потребуется некоторый механизм для получения уведомления при сборе объектов со слабыми ссылками, чтобыизбегайте попыток получить к ним доступ позже.У GC есть интерфейс для регистрации обратных вызовов finalizer , которые должны быть вызваны до того, как объект будет собран, и это выглядит как ваш лучший доступный вариант для этой цели.

В целом, я думаю, что вы спрашиваетедля выполнимо, но с большим количеством DIY, вовлеченных.На высоком уровне

  • используйте GC_MALLOC_ATOMIC() для размещения объекта-оболочки вокруг указателя на объект со слабой ссылкой.Распределение этого способа позволяет GC управлять самой оберткой без сканирования указателя в ходе анализа достижимости GC.
  • использовать GC_register_finalizer для регистрации функции финализатора, которая устанавливает указатель обертки на NULL, когдаGC решает, что указанный объект недоступен.
  • пользователи оболочки обязаны проверить, является ли указатель внутри NULL, прежде чем пытаться разыменовать его.
...