Garbage collection with glib?
Asked Answered
M

3

7

I would like to interface an garbage collected language (specifically, it's using the venerable Boehm libgc) to the glib family of APIs.

glib and gobject use reference counting internally to manage object lifetime. The normal way to wrap these is to use a garbage collected peer object which holds a reference to the glib object, and which drops the reference when the peer gets finalised; this means that the glib object is kept alive while the application is using the peer. I've done this before, and it works, but it's pretty painful and has its own problems (such as producing two peers of the same underlying object).

Given that I've got all the overhead of a garbage collector anyway, ideally what I'd like to do is to simply turn off glib's reference counting and use the garbage collector for everything. This would simplify the interface no end and hopefully improve performance.

On the face of things this would seem fairly simple --- hook up a garbage collector finaliser to the glib object finaliser, and override the ref and unref functions to be noops --- but further investigation shows there's more to it than that: glib is very fond of keeping its own allocator pools, for example, and of course I let it do that the garbage collector assume that everything in the pool is live and it'll leak.

Is persuading glib to use libgc actually feasible? If so, what other gotchas am I likely to face? What sort of glib performance impact would forcing all allocations to go through libgc produce (as opposed to using the optimised allocators currently in glib)?

(The glib docs do say that it's supposed to interface cleanly to a garbage collector...)

Mchugh answered 4/6, 2011 at 23:35 Comment(0)
M
2

No.

Since asking this I have discovered that libgc does not search memory owned by third-party libraries for references. Which means that if glib has, in its own workspace, the only reference to an object allocated via libgc, libgc will collect it and then your program will crash.

libgc is only safe to use on objects owned by the main program.

Mchugh answered 7/1, 2016 at 10:29 Comment(0)
A
2

http://mail.gnome.org/archives/gtk-devel-list/2001-February/msg00133.html is old but still relevant.

Learning how language bindings work (proxy objects, toggle references) would probably be helpful in thinking this through.

Update: oh, from hearing Boehm GC I was thinking you were trying to replace g_malloc etc. with GC, as in that old post.

If you're doing a language binding (not GC'ing C/C++) then yes that's very achievable. A good pretty manageable example to read over would be the gjs (SpiderMonkey JavaScript) codebase.

The basic idea is that you're going to have a proxy object that "holds" a GObject and often has the only reference to the GObject. But, the one complexity is toggle references: http://mail.gnome.org/archives/gtk-devel-list/2005-April/msg00095.html

You have to store the proxy object on the GObject so you can get it back (say someone does widget.get_parent(), then you need to return the same object that was previously set as the parent, by retrieving it from the C GObject). You also have to be able to go from the proxy object to the C object obviously.

Abshier answered 5/6, 2011 at 5:13 Comment(7)
Do you have anything more recent? 2001 is practically prehistory gobject-wise.Mchugh
Other than the addition of toggle refs I'm not sure the basic picture has changed since then. The big change was GtkObject to GObject in 2.0.0Abshier
I think the short answer here is that GC won't really work in C/C++ because you won't be able to run finalizers. But you could use a C++ binding with smart pointers. Years ago I prototyped a light C++ binding called Inti that was just smart pointers (just a header file almost) rather than a full wrapper.Abshier
oh, I missed you're binding a language. in that case you are fine. just copy any of the existing language bindings.Abshier
Oh, well. I was rather hoping to avoid all the reference counting nonsense by simply using the garbage collector to collect everything and so make the problem go away, but it sounds like there's just too many fiddly edge conditions for it to work reliably. Looks like I'll just have to use proxies. (After spending way too many years fighting a reference counted operating system I loathe it with a passion --- it's a pale, fiddly and hard-to-work imitation of real garbage collection...)Mchugh
you shouldn't have too much trouble as long as only your one language is involved, since there should usually be only one ref, from the proxy.Abshier
Actually, since then I've discovered that libgc won't work at all here. I've posted an answer (and deselected yours. Sorry).Mchugh
M
2

No.

Since asking this I have discovered that libgc does not search memory owned by third-party libraries for references. Which means that if glib has, in its own workspace, the only reference to an object allocated via libgc, libgc will collect it and then your program will crash.

libgc is only safe to use on objects owned by the main program.

Mchugh answered 7/1, 2016 at 10:29 Comment(0)
B
0

For future visitors, you can refer to this article (not mine): http://d.hatena.ne.jp/bellbind/20090630/1246362401.

It's written in Japanese but the code is readable.

The compilation options mentioned in https://mail.gnome.org/archives/gtk-devel-list/2001-February/msg00133.html may also work, I haven't tested it myself.

And another relavant issue on G_SLICE if you encountered it: http://www.hpl.hp.com/hosted/linux/mail-archives/gc/2011-January/004289.html.

Britteny answered 7/1, 2016 at 6:39 Comment(1)
Unfortunately g_mem_set_vtable seems obsolete without replacement.Apeak

© 2022 - 2024 — McMap. All rights reserved.