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”.
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; }