用glib进行垃圾收集?
我想将垃圾收集语言(具体来说,它使用古老的 Boehm libgc)与 glib 系列 API 接口。
glib 和 gobject 在内部使用引用计数来管理对象生命周期。包装这些的正常方法是使用垃圾收集的对等对象,该对象保存对 glib 对象的引用,并在对等点完成时删除该引用;这意味着当应用程序使用对等点时,glib 对象保持活动状态。我之前已经这样做过,并且它有效,但它非常痛苦并且有其自身的问题(例如生成同一底层对象的两个对等点)。
无论如何,考虑到我已经承担了垃圾收集器的所有开销,理想情况下我想做的就是简单地关闭 glib 的引用计数并使用垃圾收集器来处理所有事情。这将无限简化界面并有望提高性能。
从表面上看,这似乎相当简单 --- 将垃圾收集器终结器连接到 glib 对象终结器,并将 ref 和 unref 函数重写为 noops --- 但进一步的调查表明,事情远不止这些: glib例如,非常喜欢保留自己的分配器池,当然我让它这样做,垃圾收集器假设池中的所有内容都是活动的,并且会泄漏。
说服 glib 使用 libgc 实际上可行吗?如果是这样,我可能还会遇到哪些其他问题?什么样的 glib 性能影响会迫使所有分配都通过 libgc 生成(而不是使用当前 glib 中的优化分配器)?
(glib 文档确实说它应该与垃圾收集器干净地接口......)
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...)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
http://mail.gnome.org/archives/gtk -devel-list/2001-February/msg00133.html 是旧的
但仍然相关。
学习语言绑定如何工作(代理对象、切换引用)可能有助于思考这个问题。
更新:哦,从 Boehm GC 听到的消息中,我认为您正在尝试用 GC 替换 g_malloc 等,就像那篇旧文章中那样。
如果您正在进行语言绑定(而不是 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://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.
不。
自从问这个问题以来,我发现 libgc 不会搜索第三方库拥有的内存以获取引用。这意味着,如果 glib 在其自己的工作空间中拥有对通过 libgc 分配的对象的唯一引用,libgc 将收集它,然后您的程序将崩溃。
libgc 仅可安全地用于主程序拥有的对象。
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.
对于未来的访问者,您可以参考这篇文章(不是我的):http://d. hatena.ne.jp/bellbind/20090630/1246362401。
它是用日语编写的,但代码是可读的。
https://mail.gnome 中提到的编译选项。 org/archives/gtk-devel-list/2001-February/msg00133.html 也可能有效,我自己没有测试过。
如果您遇到 G_SLICE 上的另一个相关问题: http://www.hpl.hp.com/hosted/linux/mail-archives/gc/2011-January/004289.html。
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.