Утечка памяти при использовании сборки мусора с glib
Я пытаюсь интегрировать сборщик мусора Boehm с GLib в Linux, но в одном случае я обнаружил, что он не освобождает память: когда я много раз вызываю g_strsplit, у него заканчивается память и происходит ошибка сегмента. README для сборщика мусора предупредил, что может возникнуть проблема с поиском указателей внутри динамических библиотек, и может потребовать использования 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;
}
1 ответ
Начиная с GLib 2.46, g_mem_set_vtable()
ничего не делает, поэтому нет способа заставить это работать на уровне GLib, используя современную GLib. GLib теперь безоговорочно использует распределитель из libc при вызове g_malloc()
, g_new()
и т. д. Он все еще использует свой собственный GSLice
распределитель, когда вы явно используете g_slice_*()
, но он также запрашивает распределение блоков у распределителя libc.
Я предлагаю вам попробовать интегрировать сборщик мусора на уровне libc. Есть старая статья о том, как реализовать это с помощью malloc-хаков glibc, которые по сути совпадают с GMemVTable
, но на уровне glibc вместо уровня GLib. Я не пробовал это, поэтому я не знаю, насколько хорошо это работает на практике.