{"id":15115255,"url":"https://github.com/Thermadiag/micromalloc","last_synced_at":"2025-09-27T20:32:15.849Z","repository":{"id":252243525,"uuid":"839827887","full_name":"Thermadiag/micromalloc","owner":"Thermadiag","description":"Low memory overhead allocator","archived":false,"fork":false,"pushed_at":"2024-11-14T10:51:44.000Z","size":363,"stargazers_count":28,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-14T11:34:33.275Z","etag":null,"topics":["allocator","malloc","malloc-free","malloc-library","memory-allocation","memory-allocator"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Thermadiag.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-08T12:04:51.000Z","updated_at":"2024-11-14T10:51:47.000Z","dependencies_parsed_at":"2024-08-08T15:45:23.371Z","dependency_job_id":"64386c55-1555-4136-9147-78ef17031649","html_url":"https://github.com/Thermadiag/micromalloc","commit_stats":null,"previous_names":["thermadiag/micromalloc"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thermadiag%2Fmicromalloc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thermadiag%2Fmicromalloc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thermadiag%2Fmicromalloc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thermadiag%2Fmicromalloc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Thermadiag","download_url":"https://codeload.github.com/Thermadiag/micromalloc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234460505,"owners_count":18836837,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["allocator","malloc","malloc-free","malloc-library","memory-allocation","memory-allocator"],"created_at":"2024-09-26T01:43:44.264Z","updated_at":"2025-09-27T20:32:10.523Z","avatar_url":"https://github.com/Thermadiag.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"\nPurpose\n-------\n\n*Micro* is a general purpose allocator that focuses on low memory overhead.\n\nIt's key features are: \n-\tLow memory overhead and reduced fragmentation based on a combination of best-fit and segregated-fit,\n-\tO(1) allocation and deallocation,\n-\tPossibility to create independant heap objects and free all allocated memory in one call,\n-\tCan allocate memory from preallocated buffers or files using file mapping,\n-\tScale well with the number of cores,\n-\tC++ and C interfaces are provided,\n-\tWorks on Windows and most Unix systems,\n-\tCan work on systems providing a few MBs only.\n\nThe micro library behaves quite well compared to default allocators on Windows (Low-fragmentation Heap) and Linux (glibc implementation) as it often outperforms them in both space and time.\nMicro is usually (but not always) slower than well known allocators like *mimalloc*, *snmalloc*, *tbbmalloc* or *jemalloc*, but consumes far less memory in all tested use cases.\n\nThe library is written in C++14 and should compile on most platforms with gcc, clang or msvc. A header only mode is provided for quick benchmarking. \n\nA few benchmarks are available [here](md/benchmarks.md).\n\nC and C++ interfaces\n--------------------\n\nMicro library is written in C++ but the compiled library (static or shared) can be used from C only codes.\nFor pure C code, include `micro/micro.h` header. For C/C++ code, `micro/micro.hpp` should be used as it provides both C and C++ interfaces.\nSee the [examples](md/examples.md) page for more details.\n\nFurthermore, the `micro` folder can be directly included in a foreign C++ application without compilation (header-only mode). In this case, the macro `MICRO_HEADER_ONLY` must be defined.\n\nReplacing system allocator\n--------------------------\n\nMicro provides the usual hugly tricks to replace the system allocator on Windows and Unix systems. Not that it has not been tested on MacOS and Android yet.\nYou should link with the *micro_proxy* library for that instead of the default *micro* or *micro_static* ones. See this [cmake file](tests/test_cmake/CMakeLists.txt) example for more details.\n\nIn addition, the [mp](md/mp.md) command line utility is provided for quick benchmarking of the allocator on foreign applications. It basically uses LD_PRELOAD on Linux, DYLD_INSERT_LIBRARIES on MacOS and DLL injection on Windows to force the application to link with *micro_proxy*.\n\n\n(Brief) design overview\n-----------------------\n\nThe micro library divides allocations in 3 types:\n-\tBig: above 512k\n-\tMedium: under 512k\n-\tSmall: under 656 bytes.\n\nFor big allocations, pages are simply mapped/unmap on malloc/free calls, like most other allocators.\n\nFor medium allocation, the library uses a 2 level radix tree with fine grained locking that stores free chunks sorted by size. Each chunk (allocated or free) have a 16 bytes header storing various information like its size and the position of previous block.\nFree chunks are immediately splitted/merged based on requested allocations/deallocations. Therefore, medium allocations use a **best-fit with immediate coalescing policy**. Allocation and deallocation have a O(1) complexity, and support a first level of parallelism thanks to the radix tree design.\nThis approach is quite similar to the *Two-Level Segregated Fit* (TLSF) but provides a true best-fit policy instead of an approximation.\n\nSmall allocations use a standard segregated-fit strategy with 16 bytes spaced size classes. A memory block for a specific size class has a size of at most 4096 bytes and is aligned on 4096 bytes. This removed the need of the chunk header as the block header is retrieved with address masking.\nOne original detail compared to other allocators is that size class blocks are allocated from the radix tree using the medium allocation strategy. Therefore, they benefit from the radix tree parallelism, and small leftover memory chunks due to aligned allocations can be recycled for other small allocations.\n\nThe micro library uses (almost) independant arenas to increase allocation scalability based on the number of CPU cores. Each thread is attached to an arena for its lifetime in a round-robin way, and will only use other arenas when its own arena is depleted (before refuelling it with fresh pages).\nThread local caches are avoided by design as they tend to greatly increase the memory overhead with heavily multithreaded applications. By default, the number of arenas is equal to the number of CPU cores, rounded down to the previous power of 2.\n\nBy default, the micro library allocates pages by block of 512k, does not rely on memory overcommitment, and does not over align allocated pages. This allows to use it on preallocated buffers or even on files using OS file mapping utilities (see [examples](md/examples.md)).\n\nAll allocations are 16 bytes aligned.\n\nSee the [examples](md/examples.md) for more information on the library usage.\n\nNot that the micro library does **NOT** embed security features against heap exploitation (maybe in a future version).\n\nMemory usage\n------------\n\nThe micro library provides 5 possible profiles (selected at compile time) corresponding to different use cases:\n-\t**Level 0**: suitable for low memory systems. The library will allocate pages by runs of 64k only. The maximum radix tree size is bounded to 64k free chunks as well. All allocations above 64k directly call map/unmap. The maximum number of arenas is bounded to 4. Small allocations start at 256 bytes.\n-\t**Level 1**: suitable for low capability computers. The library will allocate pages by runs of 262k. The maximum number of arenas is bounded to 16. Small allocations start at 512 bytes. This level has the lowest memory overhead.\n-\t**Level 2** (default): for any kind of usage on modern platform. The library will allocate pages by runs of 524k. The maximum number of arenas is bounded to 32. Small allocations start at 656 bytes.\n-\t**Level 3 and 4**: the library will allocate pages by runs of 1MB and 2MB. Mechanims used to reduced the memory footprint (like arena depletion) are reduced. These levels are overall faster but will consume more memory. The level 4 is provided for future integration of huge page support.\n\nThe memory level is passed to cmake as a compilation option and default to 2.\nNote that the radix tree has a static memory cost per arena that will increase with the memory level. See function `micro_max_static_cost_per_arena()` to get an estimation of this cost per arena.\n\nConfiguration\n-------------\n\nThe library offers several ways to configure the global heap or independant ones.\nThe C functions `micro_set_parameter()` and `micro_set_string_parameter()` configure the global heap programmatically. The functions `micro_heap_set_parameter()` and `micro_heap_set_string_parameter()` configure the local heaps. See the [examples](md/examples.md) for more details.\n\nBy default, the global heap is configured based on the following environment variables (with default values):\n-\t**MICRO_SMALL_ALLOC_THRESHOLD**(656): max size in bytes for small allocations. Setting to 0 disable the segregated-fit policy (only medium and big allocations are used).\n-\t**MICRO_SMALL_ALLOC_FROM_RADIX_TREE**(1): enable small allocations to use the radix tree if no free chunk is found for the corresponding size class.\n-\t**MICRO_DEPLETE_ARENAS**(1): allow arenas to deplete other arenas before allocating fresh pages. This greatly reduces the memory usage at the expense of parallelism.\n-\t**MICRO_MAX_ARENAS** (CPU based): maximum number of arenas per heap. the default value depends on the memory level.\n-\t**MICRO_DISABLE_REPLACEMENT(0)**: disable malloc replacement, Windows only.\n-\t**MICRO_BACKEND_MEMORY**(0): backend pages to be kept on deallocation. If the value is \u003c= 100, it is considered as a percent of currently used memory. If \u003e= 100, it is considered as a raw maximum number of bytes.\n-\t**MICRO_MEMORY_LIMIT**(0): memory usage limit in bytes that cannot bypass the heap (0 to disable).\n-\t**MICRO_LOG_LEVEL**(0): library logging level (0 to disable).\n-\t**MICRO_LOG_DATE_FORMAT**: date format for logging various information as well as statistics. Default to \"%Y-%m-%d %H:%M:%S\".\n-\t**MICRO_PAGE_SIZE**(4096): custom page size used for allocations from a buffer or a file.\n-\t**MICRO_GROW_FACTOR**(1.6): grow factor used when allocating from a file while file growing is enabled (see MICRO_PAGE_FILE_FLAGS).\n-\t**MICRO_PROVIDER_TYPE**(0): type of memory provider (or page provider):\n\t-\t*MicroOSProvider*(0): Standard OS based page provider.\n\t-\t*MicroOSPreallocProvider*(1): Use OS API to allocate/deallocate pages, and preallocate a certain amount (defined by MICRO_PAGE_MEMORY_SIZE).\n\t-\t*MicroMemProvider*(2): Use a memory buffer to carve pages from. In this case, the heap should be configured programmatically using `micro_set_parameter()` and `micro_set_string_parameter()`.\n\t-\t*MicroFileProvider*(3): Use a memory mapped file to carve pages from. Use MICRO_PAGE_FILE_PROVIDER and MICRO_PAGE_FILE_PROVIDER_DIR for the filename and MICRO_PAGE_FILE_FLAGS for advanced configuration.\n-\t**MICRO_PAGE_FILE_PROVIDER**(null): filename for the page file provider. If null (and MICRO_PAGE_FILE_PROVIDER_DIR is null), a temporary file is created. You should use this parameter with great care, as any spawn process will use the same filename (certain crash).\n-\t**MICRO_PAGE_FILE_PROVIDER_DIR**(null): directory name for the page file provider. If not null, the file page provider will create a filename combining the directory name and MICRO_PAGE_FILE_PROVIDER (if not null) as file prefix. If MICRO_PAGE_FILE_PROVIDER is null, a generated file name is used. \n\tNote that MICRO_PAGE_FILE_PROVIDER_DIR is the preffered way to use file provider as it should always work regardless of spawn processes.\n-\t**MICRO_PAGE_MEMORY_SIZE**: start file size for file page provider (MICRO_PROVIDER_TYPE is 3), or preallocated size (MICRO_PROVIDER_TYPE is 1)\n-\t**MICRO_PAGE_FILE_FLAGS**: configuration flags for the file page provider. Combination of:\n\t-\t*MicroStaticSize*(0, default): The file has a static size defined by MICRO_PAGE_MEMORY_SIZE and cannot grow. \n\t-\t*MicroGrowing*(1): Allow the file to grow on page demand.\n-\t**MICRO_ALLOW_OS_PAGE_ALLOC**(1): to be used with MICRO_PROVIDER_TYPE \u003e 0. If set to 1, allow the usage of OS API to allocate pages when the underlying page provider is full.\n-\t**MICRO_PRINT_STATS**(null): output stream to print statistics. Can be set to \"stdout\", \"stderr\", or any filename to output statistics to a file.\n-\t**MICRO_PRINT_STATS_TRIGGER**(0): defines on which event(s) statistics are printed. Combination of:\n\t-\t*MicroNoStats*(0): statistics are never printed.\n\t-\t*MicroOnExit*(1): statistics are printed at program exit.\n\t-\t*MicroOnTime*(2): statistics are printed every MICRO_PRINT_STATS_MS milliseconds (on allocation only).\n\t-\t*MicroOnBytes*(4): statistics are printed every MICRO_PRINT_STATS_BYTES allocated bytes.\n-\t**MICRO_PRINT_STATS_MS**: used if (MICRO_PRINT_STATS_TRIGGER \u0026 MicroOnTime) != 0\n-\t**MICRO_PRINT_STATS_BYTES**: used if (MICRO_PRINT_STATS_TRIGGER \u0026 MicroOnBytes) != 0\n-\t**MICRO_PRINT_STATS_CSV**: still experimental, print statistics in CSV format\n\nBuild\n-----\n\nMicro relies on cmake for building and integration in other projects. List of all options with their default values:\n-\t**MICRO_MEMORY_LEVEL(\"2\")**: library memory level, as seen above\n-\t**MICRO_BUILD_SHARED(ON)**: build the shared version of micro\n-\t**MICRO_BUILD_STATIC(ON)**: build the static version of micro\n-\t**MICRO_BUILD_PROXY(ON)**: build the proxy version of micro for malloc replacement\n-\t**MICRO_BUILD_TESTS(ON)**: build the test executables\n-\t**MICRO_BUILD_BENCHS(ON)**: build the benchmark executable\n-\t**MICRO_BUILD_TOOLS(ON)**: build the tools executables (currently only the *mp* one)\n-\t**MICRO_ENABLE_ASSERT(OFF)**: enable release assertions to detect possible memory corruptions even on release builds\n-\t**MICRO_ZERO_MEMORY(OFF)**: zero memory on allocation\n-\t**MICRO_NO_FILE_MAPPING(OFF)**: disable the file mapping support for allocation from files\n-\t**MICRO_BENCH_MALLOC(ON)**: add standard malloc to benchmarks\n-\t**MICRO_BENCH_MIMALLOC(ON)**: add mimalloc to benchmarks\n-\t**MICRO_BENCH_SNMALLOC(OFF)**: add snmalloc to benchmarks\n-\t**MICRO_BENCH_TBB(ON)**: add tbbmalloc to benchmarks, currently Windows only\n-\t**MICRO_BENCH_JEMALLOC_PATH(\"\")**: add jemalloc to benchmarks by setting the installation path (jemalloc must be built locally, linux only)\n-\t**MICRO_NO_WARNINGS(OFF)**: Treat warnings as errors\n-\t**MICRO_ENABLE_TIME_STATISTICS(OFF)**: Enable time statistics (get average allocation/deallocation time and maximum ones)\n-\t**MICRO_NO_LOCK(OFF)**: Disable all locking mechanisms for monothreaded systems\n\nSee this [cmake file](tests/test_cmake/CMakeLists.txt) file for examples of targets using either *micro*, *micro_static* or *micro_proxy* libraries.\n\nNote that if using *micro_static*, *MICRO_STATIC* must be defined.\n\n\nBenchmarks\n----------\n\nThe library embedds several benchmarks in the `benchs` folder.\nSome of them are presented in the [benchmarks](md/benchmarks.md) page.\n\nRemaining work\n--------------\n\nThe micro library is not as complete as other general purpose allocators:\n-\tMicro library was not tested on many OS, including MacOS and Android.\n-\tThe test suite is not complete and may need extra testing features.\n-\tThe library does not embed security features against heap exploitation.\n-\tHuge pages are not yet supported.\n\nSome of these points might be addressed in the future. The library was developped for my current work projects, and additional developments will be likely driven by these projects.\n\nIn any case, all contributions are more than welcome.\n\nAcknowledgements\n----------------\n\n*Micro* library uses a simplified version of the [komihash](https://github.com/avaneev/komihash) hash function. The library was developped with ideas comming from several other generic allocators:\n-\t\u003ca href=\"https://github.com/microsoft/mimalloc\"\u003emimalloc\u003c/a\u003e,\n-\t\u003ca href=\"https://github.com/oneapi-src/oneTBB/tree/master\"\u003etbbmalloc\u003c/a\u003e which proxy method was used.\n\nThe benchmarks can include the additional following libraries:\n-\t\u003ca href=\"https://github.com/jemalloc/jemalloc\"\u003ejemalloc\u003c/a\u003e,\n-\t\u003ca href=\"https://github.com/microsoft/snmalloc\"\u003esnmalloc\u003c/a\u003e.\n\nThe benchmarks include code from:\n-\t\u003ca href=\"https://github.com/daanx/mimalloc-bench\"\u003emimalloc-bench\u003c/a\u003e,\n-\t\u003ca href=\"https://github.com/mjansson/rpmalloc-benchmark\"\u003erpmalloc-benchmark\u003c/a\u003e.\n-\t\u003ca href=\"https://github.com/r-lyeh-archived/malloc-survey/tree/master\"\u003emalloc-survey\u003c/a\u003e.\n-\t\u003ca href=\"https://github.com/node-dot-cpp/alloc-test/tree/master\"\u003ealloc-test\u003c/a\u003e.\n\n\nmicro:: library and this page Copyright (c) 2024, Victor Moncada\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FThermadiag%2Fmicromalloc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FThermadiag%2Fmicromalloc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FThermadiag%2Fmicromalloc/lists"}