mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-02 05:43:07 +02:00
257 lines
9.0 KiB
Plaintext
257 lines
9.0 KiB
Plaintext
<!-- ##### SECTION Title ##### -->
|
|
Memory Slices
|
|
|
|
<!-- ##### SECTION Short_Description ##### -->
|
|
efficient way to allocate groups of equal-sized chunks of memory
|
|
|
|
<!-- ##### SECTION Long_Description ##### -->
|
|
<para>
|
|
Memory slices provide a space-efficient and multi-processing scalable
|
|
way to allocate equal-sized pieces of memory, just like the original
|
|
#GMemChunks (from GLib <= 2.8), while avoiding their excessive
|
|
memory-waste, scalability and performance problems.
|
|
</para>
|
|
|
|
<para>
|
|
To achieve these goals, the slice allocator uses a sophisticated,
|
|
layered design that has been inspired by Bonwick's slab allocator
|
|
<footnote><para>
|
|
<ulink url="http://citeseer.ist.psu.edu/bonwick94slab.html">[Bonwick94]</ulink> Jeff Bonwick, The slab allocator: An object-caching kernel
|
|
memory allocator. USENIX 1994, and
|
|
<ulink url="http://citeseer.ist.psu.edu/bonwick01magazines.html">[Bonwick01]</ulink> Bonwick and Jonathan Adams, Magazines and vmem: Extending the
|
|
slab allocator to many cpu's and arbitrary resources. USENIX 2001
|
|
</para></footnote>.
|
|
It uses posix_memalign() to optimize allocations of many equally-sized
|
|
chunks, and has per-thread free lists (the so-called magazine layer)
|
|
to quickly satisfy allocation requests of already known structure sizes.
|
|
This is accompanied by extra caching logic to keep freed memory around
|
|
for some time before returning it to the system. Memory that is unused
|
|
due to alignment constraints is used for cache colorization (random
|
|
distribution of chunk addresses) to improve CPU cache utilization. The
|
|
caching layer of the slice allocator adapts itself to high lock contention
|
|
to improve scalability.
|
|
</para>
|
|
|
|
<para>
|
|
The slice allocator can allocate blocks as small as two pointers, and
|
|
unlike malloc(), it does not reserve extra space per block. For large block
|
|
sizes, g_slice_new() and g_slice_alloc() will automatically delegate to the
|
|
system malloc() implementation. For newly written code it is recommended
|
|
to use the new <literal>g_slice</literal> API instead of g_malloc() and
|
|
friends, as long as objects are not resized during their lifetime and the
|
|
object size used at allocation time is still available when freeing.
|
|
</para>
|
|
|
|
<example>
|
|
<title>Using the slice allocator</title>
|
|
<programlisting>
|
|
gchar *mem[10000];
|
|
gint i;
|
|
|
|
/* Allocate 10000 blocks. */
|
|
for (i = 0; i < 10000; i++)
|
|
{
|
|
mem[i] = g_slice_alloc (50);
|
|
|
|
/* Fill in the memory with some junk. */
|
|
for (j = 0; j < 50; j++)
|
|
mem[i][j] = i * j;
|
|
}
|
|
|
|
/* Now free all of the blocks. */
|
|
for (i = 0; i < 10000; i++)
|
|
{
|
|
g_slice_free1 (50, mem[i]);
|
|
}
|
|
</programlisting></example>
|
|
|
|
<example>
|
|
<title>Using the slice allocator with data structures</title>
|
|
<programlisting>
|
|
GRealArray *array;
|
|
|
|
/* Allocate one block, using the g_slice_new(<!-- -->) macro. */
|
|
array = g_slice_new (GRealArray);
|
|
|
|
/* We can now use array just like a normal pointer to a structure. */
|
|
array->data = NULL;
|
|
array->len = 0;
|
|
array->alloc = 0;
|
|
array->zero_terminated = (zero_terminated ? 1 : 0);
|
|
array->clear = (clear ? 1 : 0);
|
|
array->elt_size = elt_size;
|
|
|
|
/* We can free the block, so it can be reused. */
|
|
g_slice_free (GRealArray, array);
|
|
</programlisting></example>
|
|
|
|
<!-- ##### SECTION See_Also ##### -->
|
|
<para>
|
|
</para>
|
|
|
|
<!-- ##### SECTION Stability_Level ##### -->
|
|
|
|
|
|
<!-- ##### SECTION Image ##### -->
|
|
|
|
|
|
<!-- ##### FUNCTION g_slice_alloc ##### -->
|
|
<para>
|
|
Allocates a block of memory from the slice allocator.
|
|
The block adress handed out can be expected to be aligned
|
|
to at least <literal>1 * sizeof (void*)</literal>,
|
|
though in general slices are 2 * sizeof (void*) bytes aligned,
|
|
if a malloc() fallback implementation is used instead,
|
|
the alignment may be reduced in a libc dependent fashion.
|
|
Note that the underlying slice allocation mechanism can
|
|
be changed with the <link linkend="G_SLICE">G_SLICE=always-malloc</link>
|
|
environment variable.
|
|
</para>
|
|
|
|
@block_size: the number of bytes to allocate
|
|
@Returns: a pointer to the allocated memory block
|
|
@Since: 2.10
|
|
|
|
|
|
<!-- ##### FUNCTION g_slice_alloc0 ##### -->
|
|
<para>
|
|
Allocates a block of memory via g_slice_alloc()
|
|
and initialize the returned memory to 0.
|
|
Note that the underlying slice allocation mechanism can
|
|
be changed with the <link linkend="G_SLICE">G_SLICE=always-malloc</link>
|
|
environment variable.
|
|
</para>
|
|
|
|
@block_size: the number of bytes to allocate
|
|
@Returns: a pointer to the allocated block
|
|
@Since: 2.10
|
|
|
|
|
|
<!-- ##### FUNCTION g_slice_copy ##### -->
|
|
<para>
|
|
Allocates a block of memory from the slice allocator and copies
|
|
@block_size bytes into it from @mem_block.
|
|
</para>
|
|
|
|
@block_size: the number of bytes to allocate
|
|
@mem_block: the memory to copy
|
|
@Returns: a pointer to the allocated memory block
|
|
@Since: 2.14
|
|
|
|
|
|
<!-- ##### FUNCTION g_slice_free1 ##### -->
|
|
<para>
|
|
Frees a block of memory. The memory must have been allocated via
|
|
g_slice_alloc() or g_slice_alloc0()
|
|
and the @block_size has to match the size specified upon allocation.
|
|
Note that the exact release behaviour can be changed with the
|
|
<link linkend="G_DEBUG">G_DEBUG=gc-friendly</link> environment variable,
|
|
also see <link linkend="G_SLICE">G_SLICE</link> for related debugging options.
|
|
</para>
|
|
|
|
@block_size: the size of the block
|
|
@mem_block: a pointer to the block to free
|
|
@Since: 2.10
|
|
|
|
|
|
<!-- ##### FUNCTION g_slice_free_chain_with_offset ##### -->
|
|
<para>
|
|
Frees a linked list of memory blocks of structure type @type.
|
|
The memory blocks must be equal-sized, allocated via
|
|
g_slice_alloc() or g_slice_alloc0()
|
|
and linked together by a @next pointer (similar to #GSList). The offset
|
|
of the @next field in each block is passed as third argument.
|
|
Note that the exact release behaviour can be changed with the
|
|
<link linkend="G_DEBUG">G_DEBUG=gc-friendly</link> environment variable,
|
|
also see <link linkend="G_SLICE">G_SLICE</link> for related debugging options.
|
|
</para>
|
|
|
|
@block_size: the size of the blocks
|
|
@mem_chain: a pointer to the first block of the chain
|
|
@next_offset: the offset of the @next field in the blocks
|
|
@Since: 2.10
|
|
|
|
|
|
<!-- ##### MACRO g_slice_new ##### -->
|
|
<para>
|
|
A convenience macro to allocate a block of memory from the slice allocator.
|
|
It calls g_slice_alloc() with <literal>sizeof (@type)</literal> and casts
|
|
the returned pointer to a pointer of the given type, avoiding a type cast
|
|
in the source code.
|
|
Note that the underlying slice allocation mechanism can
|
|
be changed with the <link linkend="G_SLICE">G_SLICE=always-malloc</link>
|
|
environment variable.
|
|
</para>
|
|
|
|
@type: the type to allocate, typically a structure name
|
|
@Returns: a pointer to the allocated block, cast to a pointer to @type.
|
|
@Since: 2.10
|
|
|
|
|
|
<!-- ##### MACRO g_slice_new0 ##### -->
|
|
<para>
|
|
A convenience macro to allocate a block of memory from the slice allocator
|
|
and set the memory to 0. It calls g_slice_alloc0() with
|
|
<literal>sizeof (@type)</literal> and casts the returned pointer to a pointer
|
|
of the given type, avoiding a type cast in the source code.
|
|
Note that the underlying slice allocation mechanism can
|
|
be changed with the <link linkend="G_SLICE">G_SLICE=always-malloc</link>
|
|
environment variable.
|
|
</para>
|
|
|
|
@type: the type to allocate, typically a structure name
|
|
@Returns: a pointer to the allocated block, cast to a pointer to @type.
|
|
@Since: 2.10
|
|
|
|
|
|
<!-- ##### MACRO g_slice_dup ##### -->
|
|
<para>
|
|
A convenience macro to duplicate a block of memory using the slice allocator.
|
|
It calls g_slice_copy() with <literal>sizeof (@type)</literal> and casts
|
|
the returned pointer to a pointer of the given type, avoiding a type cast
|
|
in the source code.
|
|
Note that the underlying slice allocation mechanism can
|
|
be changed with the <link linkend="G_SLICE">G_SLICE=always-malloc</link>
|
|
environment variable.
|
|
</para>
|
|
|
|
@type: the type to duplicate, typically a structure name
|
|
@mem: the memory to copy into the allocated block
|
|
@Returns: a pointer to the allocated block, cast to a pointer to @type.
|
|
@Since: 2.14
|
|
|
|
|
|
<!-- ##### MACRO g_slice_free ##### -->
|
|
<para>
|
|
A convenience macro to free a block of memory that has been allocated
|
|
from the slice allocator. It calls g_slice_free1() using
|
|
<literal>sizeof (type)</literal> as the block size.
|
|
Note that the exact release behaviour can be changed with the
|
|
<link linkend="G_DEBUG">G_DEBUG=gc-friendly</link> environment variable,
|
|
also see <link linkend="G_SLICE">G_SLICE</link> for related debugging options.
|
|
</para>
|
|
|
|
@type: the type of the block to free, typically a structure name
|
|
@mem: a pointer to the block to free
|
|
@Since: 2.10
|
|
|
|
|
|
<!-- ##### MACRO g_slice_free_chain ##### -->
|
|
<para>
|
|
Frees a linked list of memory blocks of structure type @type.
|
|
The memory blocks must be equal-sized, allocated via
|
|
g_slice_alloc() or g_slice_alloc0() and linked together by a
|
|
@next pointer (similar to #GSList). The name of the
|
|
@next field in @type is passed as third argument.
|
|
Note that the exact release behaviour can be changed with the
|
|
<link linkend="G_DEBUG">G_DEBUG=gc-friendly</link> environment variable,
|
|
also see <link linkend="G_SLICE">G_SLICE</link> for related debugging options.
|
|
</para>
|
|
|
|
@type: the type of the @mem_chain blocks
|
|
@mem_chain: a pointer to the first block of the chain
|
|
@next: the field name of the next pointer in @type
|
|
@Since: 2.10
|
|
|
|
|