cymem
cymem is a Python library that provides efficient memory-management helpers for Cython. It simplifies tying C-level memory allocations (via `calloc`/`free`) to the lifecycle of Python objects, automatically freeing memory when the owning Python object is garbage collected. The core component is `cymem.Pool`, a thin wrapper around `calloc`. Currently at version 2.0.13, it maintains a regular release cadence, often aligning with new Python version support and performance enhancements like free-threading.
Warnings
- gotcha When `cymem.Pool` is used with CPython 3.13+ free-threaded builds (PEP 703), operations like `alloc()`, `free()`, and `realloc()` are thread-safe. However, reading the internal state (e.g., `addresses` dict) without explicit critical sections is not thread-safe. Users are also responsible for synchronizing access to the *contents* of the allocated memory across threads.
- breaking Incompatibility between `cymem`'s compiled C++ files and the installed Cython version can lead to errors like `ValueError: cymem.cymem.Pool has the wrong size, try recompiling.` This often happens when Cython's internal structures change.
- gotcha `cymem.Pool` simplifies memory deallocation by tying it to the Python object's lifecycle. However, users must still ensure that no raw C pointers obtained from the pool outlive the Python object that owns the `Pool` instance. If the `Pool` object is garbage collected, all its managed memory is freed, invalidating any lingering pointers.
Install
-
pip install cymem
Imports
- Pool
from cymem.cymem cimport Pool
Quickstart
from cymem.cymem cimport Pool
from libc.stdlib cimport sizeof
def main():
cdef Pool mem = Pool()
cdef int* data1 = <int*>mem.alloc(10, sizeof(int))
cdef float* data2 = <float*>mem.alloc(12, sizeof(float))
# Use data1 and data2
data1[0] = 100
data2[0] = 3.14
print(f"Data1 at index 0: {data1[0]}")
print(f"Data2 at index 0: {data2[0]}")
# Memory is automatically freed when 'mem' (the Pool object) is garbage collected.
# No explicit free() calls are needed for memory allocated via Pool.
# To run this, you would typically compile it with Cython:
# cython -3 --inplace your_module.pyx
# Then import and call main() from Python:
# import your_module
# your_module.main()