Login | Register

Documentation

Documentation -> Development Manual 3.3 -> Memory Management

This page has been visited 439 times.


Pages for other versions: devel 3.4 3.3 3.2 3.1 Older versions:


Memory Management

OpenSIPS has its own memory allocator. This provides some important advantages over the system memory allocator:

  • the ability to hard limit the memory that OpenSIPS uses
  • improved performance over the system memory allocator
  • multiple allocators are available, each with different use cases (a standard allocator, a memory debugging allocator – useful for debugging memory leaks and memory corruptions, and a high-performance allocator – built for highly parallel workloads on multi-core systems).


Furthermore, since OpenSIPS is a multi-process application, the use of shared memory is required in many very common scenarios. The OpenSIPS allocators also hide the shared memory implementations details and expose a very simple API, very similar to the system allocator.
On OpenSIPS startup, all custom allocators will request the maximum configured OpenSIPS memory from the operating system, and then proceed to manage it internally as OpenSIPS starts to use memory while processing traffic.
From a development perspective, there are two types of memory: one that is tied to the context of a single Process (Private Memory), and another that is shared between all OpenSIPS processes (Shared Memory).

1.  Private (PKG) Memory

Private memory is only specific to a single OpenSIPS process. Since it has no visibility outside the current process, no locking mechanisms are required while managing such memory, hence allocating private memory will be faster than allocating shared memory.

Common use case: before forking OpenSIPS processes, the developer stores some static variables in the private memory of the main process. After forking, each child process will have its own clone of the private memory chunk (same memory address pointer!).


mem/mem.h exposes all the private memory related functions

/*
Parameters :
      size - size in bytes of the request private memory
Returns :
      the actual allocated buffer, or NULL is case of error
*/

void *pkg_malloc(unsigned int size);

/*
Parameters :
      buf - the buffer to be freed
*/

void pkg_free(void *buf)

/*
Parameters :
      buf - buffer that we want to reallocate
      size - the new desired buffer size
Returns :
        the new buffer address if reallocation is successful, or NULL in case of error.

Note that pkg_realloc(NULL,size) is equivalent to pkg_malloc(size)
*/

void *pkg_realloc(void *buf, unsigned int size);

2.  Shared (SHM) Memory

Shared memory can be accessible from all OpenSIPS processes. Thus, generally speaking, all write access to a shared memory buffer should be guarded by some form of synchronization mechanism in order to ensure consistency.
Also, since allocations of chunks of shared memory can be requested from all the OpenSIPS processes, the shared memory allocator internally uses locking in order to ensure consistency. Due to this, as a general guideline, it is recommended to avoid big fragmentation of the shared memory ( by requesting many small chunks ), by merging as much information that is meaningfully tied together in a single shared memory chunk.

mem/shm_mem.h exposes all the shared memory related functions :

/*
Parameters :
      size - size in bytes of the request shared memory
Returns :
      the actual allocated buffer, or NULL is case of error
*/

void *shm_malloc(unsigned int size);

/*
Parameters :
      buf - the buffer to be freed
*/

void shm_free(void *buf)

/*
Parameters :
      buf - buffer that we want to reallocate
      size - the new desired buffer size
Returns :
        the new buffer address if reallocation is successful, or NULL in case of error.

Note that shm_realloc(NULL,size) is equivalent to shm_malloc(size)
*/

void *shm_realloc(void *buf, unsigned int size);

3.  Memory Allocators

To find out more about the strengths and weaknesses of each memory allocator, be sure to read this comprehensive blog post


Page last modified on December 11, 2019, at 06:38 PM