LINUX.ORG.RU

Как понять когда нужно делать unref?

 , , ,


0

3

Помогите разобраться в каких случая при работе с GLib и GObject происходит выделение памяти. Правильно я понимаю, что объект уничтожается когда количество ссылок на него становится равных 0? При этом высвобождается занимаемая память. Если я вызываю unref(), то количество ссылок уменьшается на 1. А в каких случаях оно растёт? Что происходит со ссылками, если я вызываю remove() или destroy() ? Есть какие-то руководства по этому делу?

★★★★★

При создании виджета у него нулевой refcount с особой пометкой, которая снимается при первом ref. Т.о. виджеты, добавленные в контейнер, не надо unref'ить. В остальных случаях надо.

Если будешь писать свои gobject'ы, читай также про dispose.

anonymous
()
Ответ на: комментарий от anonymous

Обманул тебя с начальным рефкаунтом. Изначально 1. Вот лучше сам читай. Это gtkobject, не путать с чистым gobject, у него есть понятие floating reference, чтобы не анрефить виджеты после добавления в контейнер.

http://www.gtk.org/api/2.6/gtk/GtkObject.html

anonymous
()
Ответ на: комментарий от i-rinat

А в каких случаях оно делает себе копию?

Если функция делает себе «копию», то растёт.

А в каких случаях делается копия? Вот пример из GStreamer'овского manual'а.

/* we add a message handler */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);

Есть объект pipeline. Функцией gst_pipeline_get_bus() мы узнаём указатель на такую внутреннюю сущность объекта как bus, которая тоже вроде как объект. Потом мы с этим объектом что-то делаем, а потом делаем unref. То есть нам недостаточно просто освободить ячейку памяти в которой лежит указатель на bus, нужно именно уменьшить ref_count. В какой-то момент мы создали копию bus'а, но сразу же её уничтожаем.

PS: перечитывание собственного сообщения вызывает у меня впечатление, что в голове каша.

Camel ★★★★★
() автор топика
Ответ на: А в каких случаях оно делает себе копию? от Camel

bus, которая тоже вроде как объект

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

В какой-то момент мы создали копию bus'а, но сразу же её уничтожаем.

Это не копии, а ссылки на одну и ту же область в памяти. Ведётся учёт количества ссылок на неё. Если ссылок больше ни у кого нет, память можно освобождать. Эдакая сборка мусора, только учёт ссылок производится вручную.

i-rinat ★★★★★
()

Если функция делает себе «копию», то растёт.

Инкрементирую. Иногда из документации не всегда понятно, делается ли копия. В таких случаях пишу маленькие тесты. Сразу после вызова функций делаю g_object_unref(). Если ловится ошибка, значит функция не копирует =)

greek_31 ★★
()
Ответ на: А в каких случаях оно делает себе копию? от Camel

Обычно в документации к обьектныи фреймворкам явно указывается конвенция по ref/unref. Но всегда есть или подразумевается приписка о том, что «некоторые функции могут вести себя по-другому, читай документацию». По ссылке это есть.

Общее правило в gobject: кто сделал new или ref, тот и делает unref. Остальные случаи задокументированы отдельно, как и твой.

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPi...

anonymous
()
Ответ на: комментарий от greek_31

А если refcount > 1, по к-л причинам, то молимся и ставим свечку.

anonymous
()

Вам уже достаточно полно ответили на вопрос, но я бы также порекомендовал gtkmm, это наиболее низкоуровневый ЯП из тех, на которых можно сделать работу со ссылками автоматизированными (RefPtr). Возможно вам это подойдет если вы можете использовать С++ в вашем проекте

vertexua ★★★★★
()
Ответ на: А в каких случаях оно делает себе копию? от Camel

Вообще полезно забить на подозрения о внутренних сущностях, и только считать refcount'ы, пользуясь при этом документацией. Понятие копирования тоже не стоит мешать с понятием владения.

А в общем, вряд ли возвращаемый объект будет внутренней сущностью, т.к. его возврат угрожает инкапсуляции. Исключение — когда возвращаются явно иммутабельные объекты, но понятие иммутабельности в gobject'ах я еще не встречал.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.