Сборка мусора с glib?

Я хотел бы связать язык сборки мусора (в частности, он использует почтенный Boehm libgc) с семейством API glib.

glib и gobject используют внутренний подсчет ссылок для управления временем жизни объекта. Обычный способ обернуть их - использовать одноранговый объект со сборщиком мусора, который содержит ссылку на объект glib и который удаляет ссылку, когда одноранговый узел завершается; это означает, что объект glib сохраняется, пока приложение использует одноранговый узел. Я делал это раньше, и это работает, но это довольно болезненно и имеет свои проблемы (например, создание двух пиров одного и того же базового объекта).

Учитывая, что в любом случае у меня есть все накладные расходы на сборщик мусора, в идеале я хотел бы просто отключить подсчет ссылок в glib и использовать сборщик мусора для всего. Это упростит интерфейс до бесконечности и, надеюсь, повысит производительность.

На первый взгляд, это может показаться довольно простым: подключить финализатор сборщика мусора к финализатору объекта glib и переопределить функции ref и unref, чтобы они были noops, но дальнейшее исследование показывает, что это еще не все: glib например, очень любит хранить свои собственные пулы распределителей, и, конечно, я позволю ему сделать так, чтобы сборщик мусора предположил, что все в пуле живое, и оно будет течь.

Можно ли убедить glib использовать libgc? Если да, то с какими еще проблемами я могу столкнуться? Какое влияние на производительность glib будет заставлять все выделения проходить через libgc (в отличие от использования оптимизированных распределителей, которые в настоящее время находятся в glib)?

(Документы glib говорят, что он должен чисто взаимодействовать с сборщиком мусора...)

3 ответа

Решение

Нет.

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

libgc безопасно использовать только на объектах, принадлежащих основной программе.

http://mail.gnome.org/archives/gtk-devel-list/2001-February/msg00133.html устарел, но все еще актуален.

Изучение того, как работают языковые привязки (прокси-объекты, ссылки на переключатели), вероятно, будет полезно для обдумывания этого.

Обновление: о, слушая Boehm GC, я подумал, что вы пытаетесь заменить g_malloc и т. Д. На GC, как в этом старом посте.

Если вы делаете привязку к языку (не GC'ing C/C++), тогда да, это очень достижимо. Хорошим довольно управляемым примером для чтения будет кодовая база gjs (SpiderMonkey JavaScript).

Основная идея заключается в том, что у вас будет прокси-объект, который "содержит" GObject и часто имеет единственную ссылку на GObject. Но одна сложность заключается в переключении ссылок: http://mail.gnome.org/archives/gtk-devel-list/2005-April/msg00095.html

Вы должны сохранить прокси-объект в GObject, чтобы вы могли получить его обратно (скажем, кто-то делает widget.get_parent(), затем вам нужно вернуть тот же объект, который был ранее установлен в качестве родительского, путем извлечения его из C GObject), Вы также должны иметь возможность перейти от прокси-объекта к объекту C. Очевидно,

Для будущих посетителей вы можете обратиться к этой статье (не моей): http://d.hatena.ne.jp/bellbind/20090630/1246362401.

Он написан на японском языке, но код читабелен.

Параметры компиляции, упомянутые в https://mail.gnome.org/archives/gtk-devel-list/2001-February/msg00133.html msg00133.html, также могут работать, я сам не проверял.

И еще одна актуальная проблема с G_SLICE, если вы с ней столкнулись: http://www.hpl.hp.com/hosted/linux/mail-archives/gc/2011-January/004289.html.

Другие вопросы по тегам