After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 352889 - g_mem_chunks are never given back to system memory
g_mem_chunks are never given back to system memory
Status: RESOLVED WONTFIX
Product: glib
Classification: Platform
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2006-08-25 19:06 UTC by Colin Leroy
Modified: 2008-08-16 15:25 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Colin Leroy 2006-08-25 19:06:33 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.
Comment 1 Brian Tarricone 2007-01-22 11:14:40 UTC
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).
Comment 2 Benedikt Meurer 2007-01-22 11:48:45 UTC
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.
Comment 3 Ben Hutchings 2007-02-28 15:22:20 UTC
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.
Comment 4 Matthias Clasen 2008-08-15 03:14:00 UTC
Meme chunks are deprecated, so we won't add major new features to it.
Comment 5 Benedikt Meurer 2008-08-15 08:43:21 UTC
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.
Comment 6 Tor Lillqvist 2008-08-15 09:47:15 UTC
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?
Comment 7 Benedikt Meurer 2008-08-15 11:19:22 UTC
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.
Comment 8 Colin Leroy 2008-08-16 15:25:15 UTC
(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.