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.