UHEAP Markers and Panics in GLib-based Applications

The 2.10.x version of GLib has introduced a new type of memory allocator called slice allocator. These allocators allocate memory in page sizes even for a small request of something like 20 bytes. Once a huge chunk has been allocated, all the future memory requests are granted using the chunk that was allocated for the first memory request. Once the free pool runs out, another huge chunk is allocated.

Whenever the memory is freed using g_slice_free1(), the memory is not returned to the OS; instead it is maintained by GLib as free memory which is used to for future memory requests.

The following example explains the issue. The code given below uses slice allocators to allocate 10 bytes of memory using g_slice_alloc() and subsequently frees it using g_slice_free1(). The code panics at __UHEAP_MARKEND, although the memory that has been allocated has been deallocated. This is because all the allocated memory on the heap has not been deallocated. When the user calls g_slice_free1() to free up, the memory is not freed; instead, GLib will keep it as part of the free pool for future allocation.

#include <glib.h>
#include <e32base.h>

int main()
{
  char *x;
  __UHEAP_MARK;
  x = (char *)g_slice_alloc(10);
  g_slice_free1(10,x);
  __UHEAP_MARKEND;
  return 0;
}

To get around this problem, define an environment variable G_SLICE and set it to “always-malloc”.

Note: It is necessary that this environment variable is set before any GLib call that can cause memory allocation. If the environment variable is set after any g_slice* APIs have been called either from the application code or from GLib library code, setting it has not effect.

The code below demonstrates the usage.

#include <glib.h>
#include <e32base.h>

int main()
{
  char *x;
  __UHEAP_MARK;
 	g_setenv("G_SLICE","always-malloc",1);
  x = (char *)g_slice_alloc(10);
  g_slice_free1(10,x);
 __UHEAP_MARKEND;
 return 0;
}
Note: G_SLICE is just a debugging environment variable. Setting it to “always-malloc” can help in detecting memory leaks in application code. This setting need not and should not be done in the release code since doing it overrides the GLib memory allocation mechanism and hence may result in loss of efficiency. The slice allocators are used by other GLib APIs like GList, GSList, GNode, and so on. Thus setting the environment variable is necessary if the application makes use of any such APIs that might use slice allocators.