5

我正在尝试在 Linux 中将 Boehm 垃圾收集器与 GLib 集成,但在一种情况下,我发现它没有释放内存:当我多次调用 g_strsplit 时,它会耗尽内存和段错误。垃圾收集器的自述文件警告说,它可能无法在动态库中找到指针,并且可能需要使用 GC_add_roots。

为了测试这一点,我将所有相关代码从 GLib 复制到我的源文件中,根本没有链接到 libglib-2.0.so。这消除了段错误,这告诉我这确实是问题所在。但是,没有关于如何使用 GC_add_roots 解决此问题的文档。有人能帮我吗?

这是导致内存泄漏的代码:

#include <glib.h>
#include <gc.h>

void no_free(void *mem) {}

int main() {
    g_mem_gc_friendly = TRUE;

    GMemVTable memvtable = {
        .malloc      = GC_malloc,
        .realloc     = GC_realloc,
        .free        = no_free,
        .calloc      = NULL,
        .try_malloc  = NULL,
        .try_realloc = NULL
    };

    g_mem_set_vtable(&memvtable);

    for (int i = 0; i < 10000; i++) {
        char **argv = g_strsplit("blah", " ", 0);
        argv[0][0] = 'a'; // avoid unused variable warning
    }

    return 0;
}
4

1 回答 1

1

由于 GLib 2.46,g_mem_set_vtable()什么都不做,所以没有办法使用现代 GLib 让它在 GLib 级别上工作。g_malloc()当你调用,等时, GLib 现在无条件地使用来自 libc的分配器。当你显式使用 时g_new(),它仍然使用自己的分配器,但它也从 libc 分配器请求它的块分配。GSLiceg_slice_*()

我建议您尝试在 libc 级别集成垃圾收集器。有一篇关于使用glibc 的 malloc hooks实现它的旧文章,它们与 基本相同,但在 glibc 级别而不是 GLib 级别。我还没有尝试过,所以我不知道它在实践中的效果如何。GMemVTable

于 2017-10-03T08:42:07.953 回答