2015-01-08 8 views
5

Ich versuche, den Boehm Garbage Collector mit GLib in Linux zu integrieren, aber in einem Fall habe ich festgestellt, dass es den Speicher nicht freigibt: wenn ich g_strsplit viele Male aufrufen, wird es keinen Speicher mehr haben und segfault. Das README für den Garbage Collector warnte, dass es möglicherweise Probleme gibt, Zeiger in dynamischen Bibliotheken zu finden, und die Verwendung von GC_add_roots erfordern kann.Speicherverlust bei der Verwendung von Garbage Collection mit Glib

Um dies zu testen, habe ich den gesamten relevanten Code von GLib in meine Quelldatei kopiert, ohne überhaupt mit libglib-2.0.so zu verlinken. Dies beseitigt die segfaults, was mir sagt, dass dies in der Tat das Problem ist. Es gibt jedoch keine Dokumentation zur Verwendung von GC_add_roots, um dies zu beheben. Kann mir jemand helfen?

Hier ist der Code, der den Speicherverlust verursacht:

#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; 
} 

Antwort

1

Seit Glib 2.46, g_mem_set_vtable() does nothing, so gibt es keine Möglichkeit, diese Arbeit an der GLib Ebene zu bekommen eine moderne GLib verwenden. GLib verwendet jetzt bedingungslos den Zuordner aus libc, wenn Sie g_malloc(), g_new() usw. aufrufen. Er verwendet weiterhin seinen eigenen GSLice Zuordner, wenn Sie explizit g_slice_*() verwenden, aber auch seine Blockzuweisungen vom libc-Zuordner anfordert.

Ich schlage vor, Sie versuchen, den Garbage Collector stattdessen auf der Libc-Ebene zu integrieren. Es gibt an old article über das Implementieren dieser mit glibc’s malloc hooks, die im Wesentlichen die gleichen sind wie GMemVTable, aber auf der Glibc-Ebene anstelle der GLib-Ebene. Ich habe das nicht versucht, also weiß ich nicht, wie gut es in der Praxis funktioniert.