GNOME Bugzilla – Bug 352889
g_mem_chunks are never given back to system memory
Last modified: 2008-08-16 15:25:15 UTC
Hi, From the doc at http://developer.gnome.org/doc/API/2.0/glib/glib-Memory-Chunks.html#g-mem-chunk-clean void g_mem_chunk_clean (GMemChunk *mem_chunk); Frees any blocks in a GMemChunk which are no longer being used. void g_blow_chunks (void); Calls g_mem_chunk_clean() on all GMemChunk objects. But from glib/gmem.c: void g_mem_chunk_clean (GMemChunk *mem_chunk) {} void g_blow_chunks (void) {} These are just noops, or I'm missing something? I know GMemChunks are deprecated, but lots of people will be using glib-2.8 for a while - including gtk+-2.8.
Similarly, g_mem_chunk_destroy() does not free any memory allocated by that GMemChunk now that the slice allocator is used and the mem chunk doesn't keep track of any memory that gets allocated via g_mem_chunk_alloc(). This can cause pretty bad leaks in long-running applications (such as Xfce desktop components).
According to the documentation, g_mem_chunk_destroy() "Frees all of the memory allocated for a GMemChunk." Since it effectively frees only the GMemChunk struct but not the memory allocated for the chunk, this is a serious bug.
Off the top of my head, this could make g_mem_chunk_destroy() work, though no slices can be freed before the chunk: struct _GMemChunk { guint alloc_size; /* the size of an atom */ gpointer head; }; GMemChunk* g_mem_chunk_new (const gchar *name, gint atom_size, gulong area_size, gint type) { GMemChunk *mem_chunk; g_return_val_if_fail (atom_size > 0, NULL); mem_chunk = g_slice_new (GMemChunk); mem_chunk->alloc_size = sizeof (gpointer) + atom_size; mem_chunk->head = NULL; return mem_chunk; } void g_mem_chunk_destroy (GMemChunk *mem_chunk) { g_return_if_fail (mem_chunk != NULL); g_slice_free_chain_with_offset (mem_chunk->alloc_size, mem_chunk->head, 0); g_slice_free (GMemChunk, mem_chunk); } gpointer g_mem_chunk_alloc (GMemChunk *mem_chunk) { gpointer *mem_slice; g_return_val_if_fail (mem_chunk != NULL, NULL); mem_slice = g_slice_alloc (mem_chunk->alloc_size); if (mem_slice != NULL) { *(gpointer **)mem_slice = mem_chunk->head; mem_chunk->head = mem_slice; return (gpointer **)mem_slice + 1; } else { return NULL; } } gpointer g_mem_chunk_alloc0 (GMemChunk *mem_chunk) { gpointer *mem_slice; g_return_val_if_fail (mem_chunk != NULL, NULL); mem_slice = g_slice_alloc0 (mem_chunk->alloc_size); if (result != NULL) { *(gpointer **)mem_slice = mem_chunk->head; mem_chunk->head = mem_slice; return (gpointer **)mem_slice + 1; } else { return NULL; } } void g_mem_chunk_free (GMemChunk *mem_chunk, gpointer mem) { } /* END */ But this isn't thread-safe (is that necessary?) and may not provide necessary alignment guarantees.
Meme chunks are deprecated, so we won't add major new features to it.
Well, that's about the first time, I've heard saying that the fix of a serious bug is a "major new feature", that won't be added.
The "lots of people" who keep using the long unmaintained GLib 2.8 can then presumably select somebody amongst themselves to maintain a fork of it that accepts patches? Don't distros with long-term support promises for some of their releases do this effectively anyway, for software versions that as such are not maintained by their upstream any longer?
I don't care about GLib 2.8. The point is: The GMemChunk stuff is part of the GLib API, which is meant to be "stable". But syntactic stability without semantic stability is useless. There's certainly a lot of code still using the GMemChunk stuff (for whatever reason), and this code will leak memory with newer GLib versions, which is a bug nothing less, nothing more. As a rule of thumb: Either break API/ABI if you do not plan to support stuff anymore (like GMemChunk) or maintain full API compatibility.
(In reply to comment #6) > The "lots of people" who keep using the long unmaintained GLib 2.8 can then > presumably select somebody amongst themselves to maintain a fork of it that > accepts patches? Don't distros with long-term support promises for some of > their releases do this effectively anyway, for software versions that as such > are not maintained by their upstream any longer? Yeah, great idea, what's nice with forks is that they're not sucking up much more energy than just fixing a few bugs. Bah, who cares about not leaking memory, anyway, when we'll soon have OpenGL rotative widgets and shiny stuff to copy the iPhone. and GSEAL which will enable us to do so much more, so easily! We're lucky the libc guys don't think this way.