Memory management
The following topic describes how to use the Memory Management ADDON API.
Memory management background
The Replicate ADDON Memory Management API provides Add-on developers with the ability to allocate memory for use within their add-on modules. Allocation is done in the context of memory pools, where a given pool lets the caller allocate multiple buffers, and then free them all in a single operation when the memory is no longer needed.
There are two types of memory pools available with the memory management API:
-
Global pools
Global pools are memory pools created from the memory pool provided during add-on initialization. These pools remain active until explicitly deallocated by the add-on or until the replication process ends. Use of a global pool for buffer allocation after add-on initialization needs to be protected by a critical section (in other words, it is not safe to allocate buffers using a pool that might be used at the same time on a different thread).
-
Thread-specific pools
Thread-specific pools are memory pools created from the memory pool returned by the get_ctx_pool() function when called outside of the add-on initialization. Examples of threads within a replication task using the ADDON include the Full Load threads and the Change Data Capture thread. Thread-specific pools and buffers allocated through them are automatically freed when the thread in which they were created terminates.
Memory management methods
The following methods can be called to utilize Replicate's memory management procedures.
create_pool
Creates a new memory pool from another memory pool (a “child pool”). Creating a child pool lets the developer clear or destroy the memory pool to release memory. When called during ADDON initialization (using the ar_addon_init method), the memory pool created (and its child pools) are all global memory pools. When called with thread-context memory pool, the created child pools are thread-specific memory pools.
Multiple child memory pools can be created from a given memory pool. Creation of a child pool is always thread safe, so no synchronization is needed.
Syntax
create_pool (AR_AO_MPOOL *parentPool, char *poolName, AR_AO_MPOOL **newPool);
Parameter | Type | Description |
---|---|---|
parentPool |
AR_AO_MPOOL* |
The pool to allocate from (required). |
poolName |
char* |
The new memory pool name (optional). Information note
The poolName value is assumed to be a static, unmanaged space that does not need to be freed. The value will not be copied internally. |
newPool |
AR_AO_MPOOL** |
The address of the variable where to store the pointer to the new memory pool. |
Examples
Example 1:
AR_AO_MPOOL* init_pool;
AR_AO_MEM->create_pool(context->addonPool, "ADDON_XYZ_POOL", &init_pool);
Example 2:
AR_AO_MPOOL* init_child_pool;
AR_AO_MEM->create_pool(init_pool, "ADDON_XYZ_CHILD_POOL", &init_child_pool);
destroy_pool
Deletes the given pool and deallocates the memory associated with it. Any pool allocated by the Memory Management APIs can be destroyed using this method.
If a pool is expected to be re-created later, then it is recommended to use the clear_pool method instead of the destroy_pool method, as doing so will result in better performance and reduced memory load.
Syntax
destroy_pool (AR_AO_MPOOL **pool);
Parameter | Type | Description |
---|---|---|
Pool |
AR_AO_MPOOL |
The address of the variable pointing to the pool to destroy. The variable will be set to NULL. |
Example
AR_AO_MEM->destroy_pool(&init_pool);
clear_pool
Deallocates the memory allocations associated with a given pool and destroys all child pools created from it. The clear_pool method also clears all metadata set with the set_ctx method.
Syntax
clear_pool (AR_AO_MPOOL *pool);
Parameter | Type | Description |
---|---|---|
pool |
AR_AO_MPOOL* |
The pool to clear. |
Example
AR_AO_MEM->clear_pool(init_pool);
calloc
This method allocates a memory buffer of the specified length from a given memory pool. The allocated buffer content is set to zeros.
-
Use of global memory pools for allocation outside of the ADDON initialization must be protected to prevent concurrent allocation from the same memory pool in different threads. Use of a thread-specific memory pool in the thread under which it was created does not need concurrency protection (see get_ctx_pool when creating thread-specific pools). However, it is not thread safe to do this on the same pool.
-
Failure in memory allocation will cause the process to abort.
Syntax
calloc (AR_AO_MPOOL *pool, size_t *size );
Parameter | Type | Description |
---|---|---|
pool |
AR_AO_MPOOL* |
The pool to allocate memory from. |
size |
size_t |
The size of the buffer to allocate. |
Example
init_sample_data = AR_AO_MEM->calloc(init_pool, sizeof(SAMPLE_DATA));
get_ctx_pool
Returns the context-thread memory pool. While this pool can be used directly to allocate buffers, it must never be cleared or destroyed explicitly by the add-on, as all add-ons used from the same thread share this pool. For this reason, it is recommended for add-ons to create their own thread-specific memory pool from the context-thread memory pool.
Use of the context-thread memory pool, as well as pools created from it, does not require protection when done in the same thread under which they were created.
The context-thread memory pool (and pools created from it) will be destroyed automatically when the thread ends.
Syntax
get_ctx_pool (char *poolName, AR_AO_MPOOL **pool );
Parameter | Type | Description |
---|---|---|
poolName |
char |
The pool name if one needs to be created (optional). |
pool |
AR_AO_MPOOL |
The ctx pool address that the function returns. |
Example
AR_AO_MEM->get_ctx_pool(NULL, &sample_pool);
get_ctx
Gets the metadata from the given memory pool for a given key name. This will return a null data value if the key has not yet been set (see set_ctx).
Syntax
get_ctx (AR_AO_MPOOL *pool, char *key, void **data );
Parameter | Type | Description |
---|---|---|
pool |
AR_AO_MPOOL |
The ctx pool to get the metadata from. |
key |
char |
The key for the metadata to retrieve. |
data |
void |
The user metadata associated with the returned pool. |
Example
AR_AO_MEM->get_ctx(sample_pool, "SAMPLE_DATA", &sample_data);
set_ctx
Sets metadata on the thread pool for a given key. This value can be retrieved by key name using the get_ctx method.
The set_ctx method allows registering of an optional cleanup function to be called when the memory pool is cleaned or destroyed. The cleanup function receives a single, void* parameter which is the data that was associated with the key.
The key and the data pointers are stored as-is (with no copying). The caller must ensure they are valid until the pool is destroyed.
Syntax
set_ctx (AR_AO_MPOOL *pool, char *key, void *data, AR_ADDONS_MEM_CTX_CLEANUP cleanup );
Parameter | Type | Description |
---|---|---|
pool |
AR_AO_MPOOL* |
The ctx pool. |
key |
char* |
The key for the metadata to retrieve. |
data |
void* |
The user metadata to be associated with the pool. |
cleanup |
AR_ADDONS_MEM_CTX_CLEANUP |
A pointer to a cleanup function with a single void* parameter, that is called with the data value when the pool is destroyed. |
Example
rc = AR_AO_MEM->set_ctx(sample_pool, "SAMPLE_DATA", sample_data, 0);
AR_ADDONS_STATUS
All Replicate ADDON Memory Management API calls, except for calloc, return an AR_ADDONS_STATUS status value.