Объектное управление памятью
Объектное управление памятью
API управления памятью для GObjects немного усложнен, но сама идея довольно проста: целью является обеспечить гибкую модель основанную на подсчете ссылок которая может интегрироваться в приложения использующие или требующие разных моделей управления памятью (такие как сборка мусора (garbage collection), aso...). Методы которые используются для манипулирования подсчётом ссылок описаны ниже.
Подсчёт ссылок
Таблица ниже резюмирует процесс уничтожения GObject:
Время вызова
Вызываемая функция
Параметры функции
Ремарка
Располагающая функция класса целевого типа
Экземпляр GObject
Когда расположение завершено, объект не должен содержать ссылки на любые другие члены объекта. Объект также, как ожидается, будет способен ответить на вызывающий метод клиента (возможно кодом ошибки но не нарушая память) в течение процесса завершения. Расположение может выполняться больше одного раза. Расположение должно привязываться к его родительской реализации как раз перед возвращением в вызывающую программу.
функция завершения класса целевого типа
Экземпляр GObject
Интерфейсная функция interface_finalize
В интерфейсной vtable
Практически не используется. Маловероятно что вам это понадобится.
Интерфейсная функция base_finalize
В интерфейсной vtable
Практически не используется. Маловероятно что вам это понадобится.
Функция class_finalize целевого типа
В структуре класса целевого типа
Практически не используется. Маловероятно что вам это понадобится.
Типовая функция base_finalize
В дереве иерархии классов из базового типа в целевой тип. base_init вызывается один раз для каждой сструктуры класса.
Практически не используется. Маловероятно что вам это понадобится.
Слабые ссылки
Подсчёт ссылок и циклы
Заметьте: следующий раздел был написан благодаря James Henstridge. Я надеюсь что все ваши благодарности и проклятия будут адресованы непосредственно ему.
Модель управления памятью GObject была спроектирована для более лёгкой интеграции в существующий код используя "сборку мусора". Именно поэтому процесс уничтожения разделён на две фазы: первая фаза, выполняется в обработчике размещения и должна освободить все ссылки на другие объекты. Вторая фаза, выполняется обработчиком финализации и должна завершить процесс уничтожения объекта. Объектные методы должны быть способны выполняться без программных ошибок (то есть, без segfault :) между двумя фазами.
Эти два шага процесса уничтожения очень полезны для прекращения подсчёта ссылок в циклах. В течение обнаружения циклов во внешнем коде, как только циклы обнаружены, внешний код может вызвать g_object_dispose
которая прекратит любые существующие циклы, так как она запустит обработчик размещения связанный с объектом и таким образом освободит все ссылки на другие объекты.
Внимательные читатели возможно поняли одно из правил обработчика размещения которое мы заявили немного раньше: обработчик размещения может быть вызван много раз. Предположим мы имеем цикличный подсчёт ссылок: объект A ссылается на B который в свою очередь ссылается на объект A. Предположим мы обнаружили цикл и нам необходимо уничтожить оба объекта. Один из способов сделать это - вызов g_object_dispose
для одного из объектов.
Если объект A освободит все ссылки на другие объекты, значит он освободит ссылку на объект B. Если объект B не принадлежит ни кому, значит это его последняя ссылка что означает выполнение обработчика размещения объекта B, который в свою очередь освободит ссылку на объект A. Если это последняя ссылка A, запустится обработчик размещения A, который выполнится второй раз прежде чем будет вызван обработчик финализации A !
Пример выше, который может показаться немного замысловатым, действительно может произойти если ваш GObject обрабатывается языковой привязкой. Таким образом я предполагаю что правила описанные ранее для уничтожения объекта соблюдаются. Иначе, могут произойти Очень плохие вещи.
Last updated
Was this helpful?