Boehm的保守垃圾收集器非常有用(比如Bigloo正在使用它, Guile使用类似的东西等等),特别是在Linux上(这是我唯一关心的操作系统;我使用的是Debian / Sid / x86 -64,如果是这样的话, libgc-dev
包是版本1:7.4.2-8
所以Boehm GC是7.4.2)。
但是, Boehm的GC需要知道使用它的每个线程。 其gc_pthreads_redirects.h (或多或less的内部)头文件重新定义pthread_create
为
# define pthread_create GC_pthread_create
实际上,Boehm的GC需要在新的线程调用堆栈中调用GC_pthread_create
( GC_pthread_create
正在这样做)。
过去,Glib(2.46)提供了一种使用struct GMemVTable
重新定义内存分配的方法, 该方法已被废弃 ,不能再使用 (我的Debian的libglib2.02.0-dev
软件包版本为2.50.3-2
)。 有一个g_mem_gc_friendly
全局布尔值,但是当查看Glib源代码时,它只是清除内存区域,然后释放它们。
最近的GTK3(我的libgtk-3-dev
软件包版本为3.22.11-1
)正在创build线程(对于可能与Dbus相关的东西,也许还涉及到GtkTextView …),通过Glib线程函数使用(间接) pthread_create
。 没有办法(除了修补源代码)被通知该线程创build。 我比任何GTKcallback恐怕会安装(例如使用g_signal_connect
)可能会从这些线程调用。 或者,如果我用一些可能使用(或访问)一些GC_malloc
-ed缓冲区的方法来GC_malloc
一个GTK小部件,那么这可能是一场灾难。
另一方面,GTK中有一个强大的编码规则,所有的GTK操作只能在主线程中进行。 引用Gdk3主题页:
然而, GTK + 不是线程安全的 。 你应该只使用GTK +和GDK从线程
gtk_init()
和gtk_main()
被调用。 这通常被称为“主线程”。
如果我自己遵循这个规则,我相信没有内部的GTK代码会从一些非主线程中调用我的callback(使用Boehm GC)?
我的直觉是,如果有GC_alloc
从GTK内部(不是直接由我的代码)从主线程外部调用,将发生灾难(因为这些GTK内部线程尚未启动GC_pthread_create
;可能会调用我的一些代码,例如,因为我是inheritance了一些现有的GTK小部件,或者是因为我连接了一些GTK信号,即使我自己没有在主线程之外使用GTK和Boehm GC编写代码)。
重点是Boehm的GC需要扫描每个线程中的每个堆栈,可能使用它。
FWIW,我在GTK bugzilla上报告了一个可能的bug#780815 。
一个典型的例子是GTK-3.22.11 tarball中的gtk+-3.22.11/examples/application9/
。 pthread_create
被 g_application_run
非常间接地通过g_application_run
g_bus_get_sync
GTK +不是用垃圾回收器来编写的。 您将不得不修改GDK及其构建的库,以调用GC_ *分配函数以使其工作。 简单地通知多余的GLib线程GC似乎并不是一个解决方案。
也就是说,如果GTK +和它所使用的库有一个不同于Boehm GC的堆,那么这可能不是问题。 您的应用程序可能并不完全没有内存泄漏和其他问题,但至少您编写的所有代码都将正确GC'd。