readme.md
1 2 <img align="left" width="100" height="100" src="doc/mimalloc-logo.png"/> 3 4 [<img align="right" src="https://dev.azure.com/Daan0324/mimalloc/_apis/build/status/microsoft.mimalloc?branchName=dev"/>](https://dev.azure.com/Daan0324/mimalloc/_build?definitionId=1&_a=summary) 5 6 # mimalloc 7 8 9 10 mimalloc (pronounced "me-malloc") 11 is a general purpose allocator with excellent [performance](#performance) characteristics. 12 Initially developed by Daan Leijen for the runtime systems of the 13 [Koka](https://koka-lang.github.io) and [Lean](https://github.com/leanprover/lean) languages. 14 15 Latest release tag: `v2.1.6` (2024-05-13). 16 Latest v1 tag: `v1.8.6` (2024-05-13). 17 18 mimalloc is a drop-in replacement for `malloc` and can be used in other programs 19 without code changes, for example, on dynamically linked ELF-based systems (Linux, BSD, etc.) you can use it as: 20 ``` 21 > LD_PRELOAD=/usr/lib/libmimalloc.so myprogram 22 ``` 23 It also includes a robust way to override the default allocator in [Windows](#override_on_windows). Notable aspects of the design include: 24 25 - __small and consistent__: the library is about 8k LOC using simple and 26 consistent data structures. This makes it very suitable 27 to integrate and adapt in other projects. For runtime systems it 28 provides hooks for a monotonic _heartbeat_ and deferred freeing (for 29 bounded worst-case times with reference counting). 30 Partly due to its simplicity, mimalloc has been ported to many systems (Windows, macOS, 31 Linux, WASM, various BSD's, Haiku, MUSL, etc) and has excellent support for dynamic overriding. 32 At the same time, it is an industrial strength allocator that runs (very) large scale 33 distributed services on thousands of machines with excellent worst case latencies. 34 - __free list sharding__: instead of one big free list (per size class) we have 35 many smaller lists per "mimalloc page" which reduces fragmentation and 36 increases locality -- 37 things that are allocated close in time get allocated close in memory. 38 (A mimalloc page contains blocks of one size class and is usually 64KiB on a 64-bit system). 39 - __free list multi-sharding__: the big idea! Not only do we shard the free list 40 per mimalloc page, but for each page we have multiple free lists. In particular, there 41 is one list for thread-local `free` operations, and another one for concurrent `free` 42 operations. Free-ing from another thread can now be a single CAS without needing 43 sophisticated coordination between threads. Since there will be 44 thousands of separate free lists, contention is naturally distributed over the heap, 45 and the chance of contending on a single location will be low -- this is quite 46 similar to randomized algorithms like skip lists where adding 47 a random oracle removes the need for a more complex algorithm. 48 - __eager page purging__: when a "page" becomes empty (with increased chance 49 due to free list sharding) the memory is marked to the OS as unused (reset or decommitted) 50 reducing (real) memory pressure and fragmentation, especially in long running 51 programs. 52 - __secure__: _mimalloc_ can be built in secure mode, adding guard pages, 53 randomized allocation, encrypted free lists, etc. to protect against various 54 heap vulnerabilities. The performance penalty is usually around 10% on average 55 over our benchmarks. 56 - __first-class heaps__: efficiently create and use multiple heaps to allocate across different regions. 57 A heap can be destroyed at once instead of deallocating each object separately. 58 - __bounded__: it does not suffer from _blowup_ \[1\], has bounded worst-case allocation 59 times (_wcat_) (upto OS primitives), bounded space overhead (~0.2% meta-data, with low 60 internal fragmentation), and has no internal points of contention using only atomic operations. 61 - __fast__: In our benchmarks (see [below](#performance)), 62 _mimalloc_ outperforms other leading allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc), 63 and often uses less memory. A nice property is that it does consistently well over a wide range 64 of benchmarks. There is also good huge OS page support for larger server programs. 65 66 The [documentation](https://microsoft.github.io/mimalloc) gives a full overview of the API. 67 You can read more on the design of _mimalloc_ in the [technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action) which also has detailed benchmark results. 68 69 Enjoy! 70 71 ### Branches 72 73 * `master`: latest stable release (based on `dev-slice`). 74 * `dev`: development branch for mimalloc v1. Use this branch for submitting PR's. 75 * `dev-slice`: development branch for mimalloc v2. This branch is downstream of `dev` (and is essentially equal to `dev` except for 76 `src/segment.c`) 77 78 ### Releases 79 80 Note: the `v2.x` version has a different algorithm for managing internal mimalloc pages (as slices) that tends to use reduce 81 memory usage 82 and fragmentation compared to mimalloc `v1.x` (especially for large workloads). Should otherwise have similar performance 83 (see [below](#performance)); please report if you observe any significant performance regression. 84 85 * 2024-05-13, `v1.8.6`, `v2.1.6`: Fix build errors on various (older) platforms. Refactored aligned allocation. 86 * 2024-04-22, `v1.8.4`, `v2.1.4`: Fixes various bugs and build issues. Add `MI_LIBC_MUSL` cmake flag for musl builds. 87 Free-ing code is refactored into a separate module (`free.c`). Mimalloc page info is simplified with the block size 88 directly available (and new `block_size_shift` to improve aligned block free-ing). 89 New approach to collection of abandoned segments: When 90 a thread terminates the segments it owns are abandoned (containing still live objects) and these can be 91 reclaimed by other threads. We no longer use a list of abandoned segments but this is now done using bitmaps in arena's 92 which is more concurrent (and more aggressive). Abandoned memory can now also be reclaimed if a thread frees an object in 93 an abandoned page (which can be disabled using `mi_option_abandoned_reclaim_on_free`). The option `mi_option_max_segment_reclaim` 94 gives a maximum percentage of abandoned segments that can be reclaimed per try (=10%). 95 96 * 2023-04-24, `v1.8.2`, `v2.1.2`: Fixes build issues on freeBSD, musl, and C17 (UE 5.1.1). Reduce code size/complexity 97 by removing regions and segment-cache's and only use arenas with improved memory purging -- this may improve memory 98 usage as well for larger services. Renamed options for consistency. Improved Valgrind and ASAN checking. 99 100 * 2023-04-03, `v1.8.1`, `v2.1.1`: Fixes build issues on some platforms. 101 102 * 2023-03-29, `v1.8.0`, `v2.1.0`: Improved support dynamic overriding on Windows 11. Improved tracing precision 103 with [asan](#asan) and [Valgrind](#valgrind), and added Windows event tracing [ETW](#ETW) (contributed by Xinglong He). Created an OS 104 abstraction layer to make it easier to port and separate platform dependent code (in `src/prim`). Fixed C++ STL compilation on older Microsoft C++ compilers, and various small bug fixes. 105 106 * 2022-12-23, `v1.7.9`, `v2.0.9`: Supports building with [asan](#asan) and improved [Valgrind](#valgrind) support. 107 Support arbitrary large alignments (in particular for `std::pmr` pools). 108 Added C++ STL allocators attached to a specific heap (thanks @vmarkovtsev). 109 Heap walks now visit all object (including huge objects). Support Windows nano server containers (by Johannes Schindelin,@dscho). 110 Various small bug fixes. 111 112 * 2022-11-03, `v1.7.7`, `v2.0.7`: Initial support for [Valgrind](#valgrind) for leak testing and heap block overflow 113 detection. Initial 114 support for attaching heaps to a speficic memory area (only in v2). Fix `realloc` behavior for zero size blocks, remove restriction to integral multiple of the alignment in `alloc_align`, improved aligned allocation performance, reduced contention with many threads on few processors (thank you @dposluns!), vs2022 support, support `pkg-config`, . 115 116 * 2022-04-14, `v1.7.6`, `v2.0.6`: fix fallback path for aligned OS allocation on Windows, improve Windows aligned allocation 117 even when compiling with older SDK's, fix dynamic overriding on macOS Monterey, fix MSVC C++ dynamic overriding, fix 118 warnings under Clang 14, improve performance if many OS threads are created and destroyed, fix statistics for large object 119 allocations, using MIMALLOC_VERBOSE=1 has no maximum on the number of error messages, various small fixes. 120 121 * 2022-02-14, `v1.7.5`, `v2.0.5` (alpha): fix malloc override on 122 Windows 11, fix compilation with musl, potentially reduced 123 committed memory, add `bin/minject` for Windows, 124 improved wasm support, faster aligned allocation, 125 various small fixes. 126 127 * [Older release notes](#older-release-notes) 128 129 Special thanks to: 130 131 * [David Carlier](https://devnexen.blogspot.com/) (@devnexen) for his many contributions, and making 132 mimalloc work better on many less common operating systems, like Haiku, Dragonfly, etc. 133 * Mary Feofanova (@mary3000), Evgeniy Moiseenko, and Manuel Pöter (@mpoeter) for making mimalloc TSAN checkable, and finding 134 memory model bugs using the [genMC] model checker. 135 * Weipeng Liu (@pongba), Zhuowei Li, Junhua Wang, and Jakub Szymanski, for their early support of mimalloc and deployment 136 at large scale services, leading to many improvements in the mimalloc algorithms for large workloads. 137 * Jason Gibson (@jasongibson) for exhaustive testing on large scale workloads and server environments, and finding complex bugs 138 in (early versions of) `mimalloc`. 139 * Manuel Pöter (@mpoeter) and Sam Gross(@colesbury) for finding an ABA concurrency issue in abandoned segment reclamation. Sam also created the [no GIL](https://github.com/colesbury/nogil) Python fork which 140 uses mimalloc internally. 141 142 143 [genMC]: https://plv.mpi-sws.org/genmc/ 144 145 ### Usage 146 147 mimalloc is used in various large scale low-latency services and programs, for example: 148 149 <a href="https://www.bing.com"><img height="50" align="left" src="https://upload.wikimedia.org/wikipedia/commons/e/e9/Bing_logo.svg"></a> 150 <a href="https://azure.microsoft.com/"><img height="50" align="left" src="https://upload.wikimedia.org/wikipedia/commons/a/a8/Microsoft_Azure_Logo.svg"></a> 151 <a href="https://deathstrandingpc.505games.com"><img height="100" src="doc/ds-logo.png"></a> 152 <a href="https://docs.unrealengine.com/4.26/en-US/WhatsNew/Builds/ReleaseNotes/4_25/"><img height="100" src="doc/unreal-logo.svg"></a> 153 <a href="https://cab.spbu.ru/software/spades/"><img height="100" src="doc/spades-logo.png"></a> 154 155 156 # Building 157 158 ## Windows 159 160 Open `ide/vs2022/mimalloc.sln` in Visual Studio 2022 and build. 161 The `mimalloc` project builds a static library (in `out/msvc-x64`), while the 162 `mimalloc-override` project builds a DLL for overriding malloc 163 in the entire program. 164 165 ## macOS, Linux, BSD, etc. 166 167 We use [`cmake`](https://cmake.org)<sup>1</sup> as the build system: 168 169 ``` 170 > mkdir -p out/release 171 > cd out/release 172 > cmake ../.. 173 > make 174 ``` 175 This builds the library as a shared (dynamic) 176 library (`.so` or `.dylib`), a static library (`.a`), and 177 as a single object file (`.o`). 178 179 `> sudo make install` (install the library and header files in `/usr/local/lib` and `/usr/local/include`) 180 181 You can build the debug version which does many internal checks and 182 maintains detailed statistics as: 183 184 ``` 185 > mkdir -p out/debug 186 > cd out/debug 187 > cmake -DCMAKE_BUILD_TYPE=Debug ../.. 188 > make 189 ``` 190 This will name the shared library as `libmimalloc-debug.so`. 191 192 Finally, you can build a _secure_ version that uses guard pages, encrypted 193 free lists, etc., as: 194 ``` 195 > mkdir -p out/secure 196 > cd out/secure 197 > cmake -DMI_SECURE=ON ../.. 198 > make 199 ``` 200 This will name the shared library as `libmimalloc-secure.so`. 201 Use `ccmake`<sup>2</sup> instead of `cmake` 202 to see and customize all the available build options. 203 204 Notes: 205 1. Install CMake: `sudo apt-get install cmake` 206 2. Install CCMake: `sudo apt-get install cmake-curses-gui` 207 208 209 ## Single source 210 211 You can also directly build the single `src/static.c` file as part of your project without 212 needing `cmake` at all. Make sure to also add the mimalloc `include` directory to the include path. 213 214 215 # Using the library 216 217 The preferred usage is including `<mimalloc.h>`, linking with 218 the shared- or static library, and using the `mi_malloc` API exclusively for allocation. For example, 219 ``` 220 > gcc -o myprogram -lmimalloc myfile.c 221 ``` 222 223 mimalloc uses only safe OS calls (`mmap` and `VirtualAlloc`) and can co-exist 224 with other allocators linked to the same program. 225 If you use `cmake`, you can simply use: 226 ``` 227 find_package(mimalloc 1.4 REQUIRED) 228 ``` 229 in your `CMakeLists.txt` to find a locally installed mimalloc. Then use either: 230 ``` 231 target_link_libraries(myapp PUBLIC mimalloc) 232 ``` 233 to link with the shared (dynamic) library, or: 234 ``` 235 target_link_libraries(myapp PUBLIC mimalloc-static) 236 ``` 237 to link with the static library. See `test\CMakeLists.txt` for an example. 238 239 For best performance in C++ programs, it is also recommended to override the 240 global `new` and `delete` operators. For convenience, mimalloc provides 241 [`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) which does this for you -- just include it in a single(!) source file in your project. 242 In C++, mimalloc also provides the `mi_stl_allocator` struct which implements the `std::allocator` 243 interface. 244 245 You can pass environment variables to print verbose messages (`MIMALLOC_VERBOSE=1`) 246 and statistics (`MIMALLOC_SHOW_STATS=1`) (in the debug version): 247 ``` 248 > env MIMALLOC_SHOW_STATS=1 ./cfrac 175451865205073170563711388363 249 250 175451865205073170563711388363 = 374456281610909315237213 * 468551 251 252 heap stats: peak total freed unit 253 normal 2: 16.4 kb 17.5 mb 17.5 mb 16 b ok 254 normal 3: 16.3 kb 15.2 mb 15.2 mb 24 b ok 255 normal 4: 64 b 4.6 kb 4.6 kb 32 b ok 256 normal 5: 80 b 118.4 kb 118.4 kb 40 b ok 257 normal 6: 48 b 48 b 48 b 48 b ok 258 normal 17: 960 b 960 b 960 b 320 b ok 259 260 heap stats: peak total freed unit 261 normal: 33.9 kb 32.8 mb 32.8 mb 1 b ok 262 huge: 0 b 0 b 0 b 1 b ok 263 total: 33.9 kb 32.8 mb 32.8 mb 1 b ok 264 malloc requested: 32.8 mb 265 266 committed: 58.2 kb 58.2 kb 58.2 kb 1 b ok 267 reserved: 2.0 mb 2.0 mb 2.0 mb 1 b ok 268 reset: 0 b 0 b 0 b 1 b ok 269 segments: 1 1 1 270 -abandoned: 0 271 pages: 6 6 6 272 -abandoned: 0 273 mmaps: 3 274 mmap fast: 0 275 mmap slow: 1 276 threads: 0 277 elapsed: 2.022s 278 process: user: 1.781s, system: 0.016s, faults: 756, reclaims: 0, rss: 2.7 mb 279 ``` 280 281 The above model of using the `mi_` prefixed API is not always possible 282 though in existing programs that already use the standard malloc interface, 283 and another option is to override the standard malloc interface 284 completely and redirect all calls to the _mimalloc_ library instead . 285 286 ## Environment Options 287 288 You can set further options either programmatically (using [`mi_option_set`](https://microsoft.github.io/mimalloc/group__options.html)), or via environment variables: 289 290 - `MIMALLOC_SHOW_STATS=1`: show statistics when the program terminates. 291 - `MIMALLOC_VERBOSE=1`: show verbose messages. 292 - `MIMALLOC_SHOW_ERRORS=1`: show error and warning messages. 293 294 Advanced options: 295 296 - `MIMALLOC_ARENA_EAGER_COMMIT=2`: turns on eager commit for the large arenas (usually 1GiB) from which mimalloc 297 allocates segments and pages. Set this to 2 (default) to 298 only enable this on overcommit systems (e.g. Linux). Set this to 1 to enable explicitly on other systems 299 as well (like Windows or macOS) which may improve performance (as the whole arena is committed at once). 300 Note that eager commit only increases the commit but not the actual the peak resident set 301 (rss) so it is generally ok to enable this. 302 - `MIMALLOC_PURGE_DELAY=N`: the delay in `N` milli-seconds (by default `10`) after which mimalloc will purge 303 OS pages that are not in use. This signals to the OS that the underlying physical memory can be reused which 304 can reduce memory fragmentation especially in long running (server) programs. Setting `N` to `0` purges immediately when 305 a page becomes unused which can improve memory usage but also decreases performance. Setting `N` to a higher 306 value like `100` can improve performance (sometimes by a lot) at the cost of potentially using more memory at times. 307 Setting it to `-1` disables purging completely. 308 - `MIMALLOC_PURGE_DECOMMITS=1`: By default "purging" memory means unused memory is decommitted (`MEM_DECOMMIT` on Windows, 309 `MADV_DONTNEED` (which decresease rss immediately) on `mmap` systems). Set this to 0 to instead "reset" unused 310 memory on a purge (`MEM_RESET` on Windows, generally `MADV_FREE` (which does not decrease rss immediately) on `mmap` systems). 311 Mimalloc generally does not "free" OS memory but only "purges" OS memory, in other words, it tries to keep virtual 312 address ranges and decommits within those ranges (to make the underlying physical memory available to other processes). 313 314 Further options for large workloads and services: 315 316 - `MIMALLOC_USE_NUMA_NODES=N`: pretend there are at most `N` NUMA nodes. If not set, the actual NUMA nodes are detected 317 at runtime. Setting `N` to 1 may avoid problems in some virtual environments. Also, setting it to a lower number than 318 the actual NUMA nodes is fine and will only cause threads to potentially allocate more memory across actual NUMA 319 nodes (but this can happen in any case as NUMA local allocation is always a best effort but not guaranteed). 320 - `MIMALLOC_ALLOW_LARGE_OS_PAGES=1`: use large OS pages (2 or 4MiB) when available; for some workloads this can significantly 321 improve performance. When this option is disabled, it also disables transparent huge pages (THP) for the process 322 (on Linux and Android). Use `MIMALLOC_VERBOSE` to check if the large OS pages are enabled -- usually one needs 323 to explicitly give permissions for large OS pages (as on [Windows][windows-huge] and [Linux][linux-huge]). However, sometimes 324 the OS is very slow to reserve contiguous physical memory for large OS pages so use with care on systems that 325 can have fragmented memory (for that reason, we generally recommend to use `MIMALLOC_RESERVE_HUGE_OS_PAGES` instead whenever possible). 326 - `MIMALLOC_RESERVE_HUGE_OS_PAGES=N`: where `N` is the number of 1GiB _huge_ OS pages. This reserves the huge pages at 327 startup and sometimes this can give a large (latency) performance improvement on big workloads. 328 Usually it is better to not use `MIMALLOC_ALLOW_LARGE_OS_PAGES=1` in combination with this setting. Just like large 329 OS pages, use with care as reserving 330 contiguous physical memory can take a long time when memory is fragmented (but reserving the huge pages is done at 331 startup only once). 332 Note that we usually need to explicitly give permission for huge OS pages (as on [Windows][windows-huge] and [Linux][linux-huge])). 333 With huge OS pages, it may be beneficial to set the setting 334 `MIMALLOC_EAGER_COMMIT_DELAY=N` (`N` is 1 by default) to delay the initial `N` segments (of 4MiB) 335 of a thread to not allocate in the huge OS pages; this prevents threads that are short lived 336 and allocate just a little to take up space in the huge OS page area (which cannot be purged as huge OS pages are pinned 337 to physical memory). 338 The huge pages are usually allocated evenly among NUMA nodes. 339 We can use `MIMALLOC_RESERVE_HUGE_OS_PAGES_AT=N` where `N` is the numa node (starting at 0) to allocate all 340 the huge pages at a specific numa node instead. 341 342 Use caution when using `fork` in combination with either large or huge OS pages: on a fork, the OS uses copy-on-write 343 for all pages in the original process including the huge OS pages. When any memory is now written in that area, the 344 OS will copy the entire 1GiB huge page (or 2MiB large page) which can cause the memory usage to grow in large increments. 345 346 [linux-huge]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/tuning_and_optimizing_red_hat_enterprise_linux_for_oracle_9i_and_10g_databases/sect-oracle_9i_and_10g_tuning_guide-large_memory_optimization_big_pages_and_huge_pages-configuring_huge_pages_in_red_hat_enterprise_linux_4_or_5 347 [windows-huge]: https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-2017 348 349 ## Secure Mode 350 351 _mimalloc_ can be build in secure mode by using the `-DMI_SECURE=ON` flags in `cmake`. This build enables various mitigations 352 to make mimalloc more robust against exploits. In particular: 353 354 - All internal mimalloc pages are surrounded by guard pages and the heap metadata is behind a guard page as well (so a buffer overflow 355 exploit cannot reach into the metadata). 356 - All free list pointers are 357 [encoded](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396) 358 with per-page keys which is used both to prevent overwrites with a known pointer, as well as to detect heap corruption. 359 - Double free's are detected (and ignored). 360 - The free lists are initialized in a random order and allocation randomly chooses between extension and reuse within a page to 361 mitigate against attacks that rely on a predicable allocation order. Similarly, the larger heap blocks allocated by mimalloc 362 from the OS are also address randomized. 363 364 As always, evaluate with care as part of an overall security strategy as all of the above are mitigations but not guarantees. 365 366 ## Debug Mode 367 368 When _mimalloc_ is built using debug mode, various checks are done at runtime to catch development errors. 369 370 - Statistics are maintained in detail for each object size. They can be shown using `MIMALLOC_SHOW_STATS=1` at runtime. 371 - All objects have padding at the end to detect (byte precise) heap block overflows. 372 - Double free's, and freeing invalid heap pointers are detected. 373 - Corrupted free-lists and some forms of use-after-free are detected. 374 375 376 # Overriding Standard Malloc 377 378 Overriding the standard `malloc` (and `new`) can be done either _dynamically_ or _statically_. 379 380 ## Dynamic override 381 382 This is the recommended way to override the standard malloc interface. 383 384 ### Dynamic Override on Linux, BSD 385 386 On these ELF-based systems we preload the mimalloc shared 387 library so all calls to the standard `malloc` interface are 388 resolved to the _mimalloc_ library. 389 ``` 390 > env LD_PRELOAD=/usr/lib/libmimalloc.so myprogram 391 ``` 392 393 You can set extra environment variables to check that mimalloc is running, 394 like: 395 ``` 396 > env MIMALLOC_VERBOSE=1 LD_PRELOAD=/usr/lib/libmimalloc.so myprogram 397 ``` 398 or run with the debug version to get detailed statistics: 399 ``` 400 > env MIMALLOC_SHOW_STATS=1 LD_PRELOAD=/usr/lib/libmimalloc-debug.so myprogram 401 ``` 402 403 ### Dynamic Override on MacOS 404 405 On macOS we can also preload the mimalloc shared 406 library so all calls to the standard `malloc` interface are 407 resolved to the _mimalloc_ library. 408 ``` 409 > env DYLD_INSERT_LIBRARIES=/usr/lib/libmimalloc.dylib myprogram 410 ``` 411 412 Note that certain security restrictions may apply when doing this from 413 the [shell](https://stackoverflow.com/questions/43941322/dyld-insert-libraries-ignored-when-calling-application-through-bash). 414 415 416 ### Dynamic Override on Windows 417 418 <span id="override_on_windows">Dynamically overriding on mimalloc on Windows</span> 419 is robust and has the particular advantage to be able to redirect all malloc/free calls that go through 420 the (dynamic) C runtime allocator, including those from other DLL's or libraries. 421 As it intercepts all allocation calls on a low level, it can be used reliably 422 on large programs that include other 3rd party components. 423 There are four requirements to make the overriding work robustly: 424 425 1. Use the C-runtime library as a DLL (using the `/MD` or `/MDd` switch). 426 2. Link your program explicitly with `mimalloc-override.dll` library. 427 To ensure the `mimalloc-override.dll` is loaded at run-time it is easiest to insert some 428 call to the mimalloc API in the `main` function, like `mi_version()` 429 (or use the `/INCLUDE:mi_version` switch on the linker). See the `mimalloc-override-test` project 430 for an example on how to use this. 431 3. The [`mimalloc-redirect.dll`](bin) (or `mimalloc-redirect32.dll`) must be put 432 in the same folder as the main `mimalloc-override.dll` at runtime (as it is a dependency of that DLL). 433 The redirection DLL ensures that all calls to the C runtime malloc API get redirected to 434 mimalloc functions (which reside in `mimalloc-override.dll`). 435 4. Ensure the `mimalloc-override.dll` comes as early as possible in the import 436 list of the final executable (so it can intercept all potential allocations). 437 438 For best performance on Windows with C++, it 439 is also recommended to also override the `new`/`delete` operations (by including 440 [`mimalloc-new-delete.h`](include/mimalloc-new-delete.h) 441 a single(!) source file in your project). 442 443 The environment variable `MIMALLOC_DISABLE_REDIRECT=1` can be used to disable dynamic 444 overriding at run-time. Use `MIMALLOC_VERBOSE=1` to check if mimalloc was successfully redirected. 445 446 We cannot always re-link an executable with `mimalloc-override.dll`, and similarly, we cannot always 447 ensure the the DLL comes first in the import table of the final executable. 448 In many cases though we can patch existing executables without any recompilation 449 if they are linked with the dynamic C runtime (`ucrtbase.dll`) -- just put the `mimalloc-override.dll` 450 into the import table (and put `mimalloc-redirect.dll` in the same folder) 451 Such patching can be done for example with [CFF Explorer](https://ntcore.com/?page_id=388) or 452 the [`minject`](bin) program. 453 454 ## Static override 455 456 On Unix-like systems, you can also statically link with _mimalloc_ to override the standard 457 malloc interface. The recommended way is to link the final program with the 458 _mimalloc_ single object file (`mimalloc.o`). We use 459 an object file instead of a library file as linkers give preference to 460 that over archives to resolve symbols. To ensure that the standard 461 malloc interface resolves to the _mimalloc_ library, link it as the first 462 object file. For example: 463 ``` 464 > gcc -o myprogram mimalloc.o myfile1.c ... 465 ``` 466 467 Another way to override statically that works on all platforms, is to 468 link statically to mimalloc (as shown in the introduction) and include a 469 header file in each source file that re-defines `malloc` etc. to `mi_malloc`. 470 This is provided by [`mimalloc-override.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-override.h). This only works reliably though if all sources are 471 under your control or otherwise mixing of pointers from different heaps may occur! 472 473 474 # Tools 475 476 Generally, we recommend using the standard allocator with memory tracking tools, but mimalloc 477 can also be build to support the [address sanitizer][asan] or the excellent [Valgrind] tool. 478 Moreover, it can be build to support Windows event tracing ([ETW]). 479 This has a small performance overhead but does allow detecting memory leaks and byte-precise 480 buffer overflows directly on final executables. See also the `test/test-wrong.c` file to test with various tools. 481 482 ## Valgrind 483 484 To build with [valgrind] support, use the `MI_TRACK_VALGRIND=ON` cmake option: 485 486 ``` 487 > cmake ../.. -DMI_TRACK_VALGRIND=ON 488 ``` 489 490 This can also be combined with secure mode or debug mode. 491 You can then run your programs directly under valgrind: 492 493 ``` 494 > valgrind <myprogram> 495 ``` 496 497 If you rely on overriding `malloc`/`free` by mimalloc (instead of using the `mi_malloc`/`mi_free` API directly), 498 you also need to tell `valgrind` to not intercept those calls itself, and use: 499 500 ``` 501 > MIMALLOC_SHOW_STATS=1 valgrind --soname-synonyms=somalloc=*mimalloc* -- <myprogram> 502 ``` 503 504 By setting the `MIMALLOC_SHOW_STATS` environment variable you can check that mimalloc is indeed 505 used and not the standard allocator. Even though the [Valgrind option][valgrind-soname] 506 is called `--soname-synonyms`, this also 507 works when overriding with a static library or object file. Unfortunately, it is not possible to 508 dynamically override mimalloc using `LD_PRELOAD` together with `valgrind`. 509 See also the `test/test-wrong.c` file to test with `valgrind`. 510 511 Valgrind support is in its initial development -- please report any issues. 512 513 [Valgrind]: https://valgrind.org/ 514 [valgrind-soname]: https://valgrind.org/docs/manual/manual-core.html#opt.soname-synonyms 515 516 ## ASAN 517 518 To build with the address sanitizer, use the `-DMI_TRACK_ASAN=ON` cmake option: 519 520 ``` 521 > cmake ../.. -DMI_TRACK_ASAN=ON 522 ``` 523 524 This can also be combined with secure mode or debug mode. 525 You can then run your programs as:' 526 527 ``` 528 > ASAN_OPTIONS=verbosity=1 <myprogram> 529 ``` 530 531 When you link a program with an address sanitizer build of mimalloc, you should 532 generally compile that program too with the address sanitizer enabled. 533 For example, assuming you build mimalloc in `out/debug`: 534 535 ``` 536 clang -g -o test-wrong -Iinclude test/test-wrong.c out/debug/libmimalloc-asan-debug.a -lpthread -fsanitize=address -fsanitize-recover=address 537 ``` 538 539 Since the address sanitizer redirects the standard allocation functions, on some platforms (macOSX for example) 540 it is required to compile mimalloc with `-DMI_OVERRIDE=OFF`. 541 Adress sanitizer support is in its initial development -- please report any issues. 542 543 [asan]: https://github.com/google/sanitizers/wiki/AddressSanitizer 544 545 ## ETW 546 547 Event tracing for Windows ([ETW]) provides a high performance way to capture all allocations though 548 mimalloc and analyze them later. To build with ETW support, use the `-DMI_TRACK_ETW=ON` cmake option. 549 550 You can then capture an allocation trace using the Windows performance recorder (WPR), using the 551 `src/prim/windows/etw-mimalloc.wprp` profile. In an admin prompt, you can use: 552 ``` 553 > wpr -start src\prim\windows\etw-mimalloc.wprp -filemode 554 > <my_mimalloc_program> 555 > wpr -stop <my_mimalloc_program>.etl 556 ``` 557 and then open `<my_mimalloc_program>.etl` in the Windows Performance Analyzer (WPA), or 558 use a tool like [TraceControl] that is specialized for analyzing mimalloc traces. 559 560 [ETW]: https://learn.microsoft.com/en-us/windows-hardware/test/wpt/event-tracing-for-windows 561 [TraceControl]: https://github.com/xinglonghe/TraceControl 562 563 564 # Performance 565 566 Last update: 2021-01-30 567 568 We tested _mimalloc_ against many other top allocators over a wide 569 range of benchmarks, ranging from various real world programs to 570 synthetic benchmarks that see how the allocator behaves under more 571 extreme circumstances. In our benchmark suite, _mimalloc_ outperforms other leading 572 allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc), and has a similar memory footprint. A nice property is that it 573 does consistently well over the wide range of benchmarks. 574 575 General memory allocators are interesting as there exists no algorithm that is 576 optimal -- for a given allocator one can usually construct a workload 577 where it does not do so well. The goal is thus to find an allocation 578 strategy that performs well over a wide range of benchmarks without 579 suffering from (too much) underperformance in less common situations. 580 581 As always, interpret these results with care since some benchmarks test synthetic 582 or uncommon situations that may never apply to your workloads. For example, most 583 allocators do not do well on `xmalloc-testN` but that includes even the best 584 industrial allocators like _jemalloc_ and _tcmalloc_ that are used in some of 585 the world's largest systems (like Chrome or FreeBSD). 586 587 Also, the benchmarks here do not measure the behaviour on very large and long-running server workloads, 588 or worst-case latencies of allocation. Much work has gone into `mimalloc` to work well on such 589 workloads (for example, to reduce virtual memory fragmentation on long-running services) 590 but such optimizations are not always reflected in the current benchmark suite. 591 592 We show here only an overview -- for 593 more specific details and further benchmarks we refer to the 594 [technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action). 595 The benchmark suite is automated and available separately 596 as [mimalloc-bench](https://github.com/daanx/mimalloc-bench). 597 598 599 ## Benchmark Results on a 16-core AMD 5950x (Zen3) 600 601 Testing on the 16-core AMD 5950x processor at 3.4Ghz (4.9Ghz boost), with 602 with 32GiB memory at 3600Mhz, running Ubuntu 20.04 with glibc 2.31 and GCC 9.3.0. 603 604 We measure three versions of _mimalloc_: the main version `mi` (tag:v1.7.0), 605 the new v2.0 beta version as `xmi` (tag:v2.0.0), and the main version in secure mode as `smi` (tag:v1.7.0). 606 607 The other allocators are 608 Google's [_tcmalloc_](https://github.com/gperftools/gperftools) (`tc`, tag:gperftools-2.8.1) used in Chrome, 609 Facebook's [_jemalloc_](https://github.com/jemalloc/jemalloc) (`je`, tag:5.2.1) by Jason Evans used in Firefox and FreeBSD, 610 the Intel thread building blocks [allocator](https://github.com/intel/tbb) (`tbb`, tag:v2020.3), 611 [rpmalloc](https://github.com/mjansson/rpmalloc) (`rp`,tag:1.4.1) by Mattias Jansson, 612 the original scalable [_Hoard_](https://github.com/emeryberger/Hoard) (git:d880f72) allocator by Emery Berger \[1], 613 the memory compacting [_Mesh_](https://github.com/plasma-umass/Mesh) (git:67ff31a) allocator by 614 Bobby Powers _et al_ \[8], 615 and finally the default system allocator (`glibc`, 2.31) (based on _PtMalloc2_). 616 617 <img width="90%" src="doc/bench-2021/bench-amd5950x-2021-01-30-a.svg"/> 618 <img width="90%" src="doc/bench-2021/bench-amd5950x-2021-01-30-b.svg"/> 619 620 Any benchmarks ending in `N` run on all 32 logical cores in parallel. 621 Results are averaged over 10 runs and reported relative 622 to mimalloc (where 1.2 means it took 1.2× longer to run). 623 The legend also contains the _overall relative score_ between the 624 allocators where 100 points is the maximum if an allocator is fastest on 625 all benchmarks. 626 627 The single threaded _cfrac_ benchmark by Dave Barrett is an implementation of 628 continued fraction factorization which uses many small short-lived allocations. 629 All allocators do well on such common usage, where _mimalloc_ is just a tad 630 faster than _tcmalloc_ and 631 _jemalloc_. 632 633 The _leanN_ program is interesting as a large realistic and 634 concurrent workload of the [Lean](https://github.com/leanprover/lean) 635 theorem prover compiling its own standard library, and there is a 13% 636 speedup over _tcmalloc_. This is 637 quite significant: if Lean spends 20% of its time in the 638 allocator that means that _mimalloc_ is 1.6× faster than _tcmalloc_ 639 here. (This is surprising as that is not measured in a pure 640 allocation benchmark like _alloc-test_. We conjecture that we see this 641 outsized improvement here because _mimalloc_ has better locality in 642 the allocation which improves performance for the *other* computations 643 in a program as well). 644 645 The single threaded _redis_ benchmark again show that most allocators do well on such workloads. 646 647 The _larsonN_ server benchmark by Larson and Krishnan \[2] allocates and frees between threads. They observed this 648 behavior (which they call _bleeding_) in actual server applications, and the benchmark simulates this. 649 Here, _mimalloc_ is quite a bit faster than _tcmalloc_ and _jemalloc_ probably due to the object migration between different threads. 650 651 The _mstressN_ workload performs many allocations and re-allocations, 652 and migrates objects between threads (as in _larsonN_). However, it also 653 creates and destroys the _N_ worker threads a few times keeping some objects 654 alive beyond the life time of the allocating thread. We observed this 655 behavior in many larger server applications. 656 657 The [_rptestN_](https://github.com/mjansson/rpmalloc-benchmark) benchmark 658 by Mattias Jansson is a allocator test originally designed 659 for _rpmalloc_, and tries to simulate realistic allocation patterns over 660 multiple threads. Here the differences between allocators become more apparent. 661 662 The second benchmark set tests specific aspects of the allocators and 663 shows even more extreme differences between them. 664 665 The _alloc-test_, by 666 [OLogN Technologies AG](http://ithare.com/testing-memory-allocators-ptmalloc2-tcmalloc-hoard-jemalloc-while-trying-to-simulate-real-world-loads/), is a very allocation intensive benchmark doing millions of 667 allocations in various size classes. The test is scaled such that when an 668 allocator performs almost identically on _alloc-test1_ as _alloc-testN_ it 669 means that it scales linearly. 670 671 The _sh6bench_ and _sh8bench_ benchmarks are 672 developed by [MicroQuill](http://www.microquill.com/) as part of SmartHeap. 673 In _sh6bench_ _mimalloc_ does much 674 better than the others (more than 2.5× faster than _jemalloc_). 675 We cannot explain this well but believe it is 676 caused in part by the "reverse" free-ing pattern in _sh6bench_. 677 The _sh8bench_ is a variation with object migration 678 between threads; whereas _tcmalloc_ did well on _sh6bench_, the addition of object migration causes it to be 10× slower than before. 679 680 The _xmalloc-testN_ benchmark by Lever and Boreham \[5] and Christian Eder, simulates an asymmetric workload where 681 some threads only allocate, and others only free -- they observed this pattern in 682 larger server applications. Here we see that 683 the _mimalloc_ technique of having non-contended sharded thread free 684 lists pays off as it outperforms others by a very large margin. Only _rpmalloc_, _tbb_, and _glibc_ also scale well on this benchmark. 685 686 The _cache-scratch_ benchmark by Emery Berger \[1], and introduced with 687 the Hoard allocator to test for _passive-false_ sharing of cache lines. 688 With a single thread they all 689 perform the same, but when running with multiple threads the potential allocator 690 induced false sharing of the cache lines can cause large run-time differences. 691 Crundal \[6] describes in detail why the false cache line sharing occurs in the _tcmalloc_ design, and also discusses how this 692 can be avoided with some small implementation changes. 693 Only the _tbb_, _rpmalloc_ and _mesh_ allocators also avoid the 694 cache line sharing completely, while _Hoard_ and _glibc_ seem to mitigate 695 the effects. Kukanov and Voss \[7] describe in detail 696 how the design of _tbb_ avoids the false cache line sharing. 697 698 699 ## On a 36-core Intel Xeon 700 701 For completeness, here are the results on a big Amazon 702 [c5.18xlarge](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized) instance 703 consisting of a 2×18-core Intel Xeon (Cascade Lake) at 3.4GHz (boost 3.5GHz) 704 with 144GiB ECC memory, running Ubuntu 20.04 with glibc 2.31, GCC 9.3.0, and 705 Clang 10.0.0. This time, the mimalloc allocators (mi, xmi, and smi) were 706 compiled with the Clang compiler instead of GCC. 707 The results are similar to the AMD results but it is interesting to 708 see the differences in the _larsonN_, _mstressN_, and _xmalloc-testN_ benchmarks. 709 710 <img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg"/> 711 <img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg"/> 712 713 714 ## Peak Working Set 715 716 The following figure shows the peak working set (rss) of the allocators 717 on the benchmarks (on the c5.18xlarge instance). 718 719 <img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg"/> 720 <img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg"/> 721 722 Note that the _xmalloc-testN_ memory usage should be disregarded as it 723 allocates more the faster the program runs. Similarly, memory usage of 724 _larsonN_, _mstressN_, _rptestN_ and _sh8bench_ can vary depending on scheduling and 725 speed. Nevertheless, we hope to improve the memory usage on _mstressN_ 726 and _rptestN_ (just as _cfrac_, _larsonN_ and _sh8bench_ have a small working set which skews the results). 727 728 <!-- 729 # Previous Benchmarks 730 731 Todo: should we create a separate page for this? 732 733 ## Benchmark Results on 36-core Intel: 2020-01-20 734 735 Testing on a big Amazon EC2 compute instance 736 ([c5.18xlarge](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized)) 737 consisting of a 72 processor Intel Xeon at 3GHz 738 with 144GiB ECC memory, running Ubuntu 18.04.1 with glibc 2.27 and GCC 7.4.0. 739 The measured allocators are _mimalloc_ (xmi, tag:v1.4.0, page reset enabled) 740 and its secure build as _smi_, 741 Google's [_tcmalloc_](https://github.com/gperftools/gperftools) (tc, tag:gperftools-2.7) used in Chrome, 742 Facebook's [_jemalloc_](https://github.com/jemalloc/jemalloc) (je, tag:5.2.1) by Jason Evans used in Firefox and FreeBSD, 743 the Intel thread building blocks [allocator](https://github.com/intel/tbb) (tbb, tag:2020), 744 [rpmalloc](https://github.com/mjansson/rpmalloc) (rp,tag:1.4.0) by Mattias Jansson, 745 the original scalable [_Hoard_](https://github.com/emeryberger/Hoard) (tag:3.13) allocator by Emery Berger \[1], 746 the memory compacting [_Mesh_](https://github.com/plasma-umass/Mesh) (git:51222e7) allocator by 747 Bobby Powers _et al_ \[8], 748 and finally the default system allocator (glibc, 2.27) (based on _PtMalloc2_). 749 750 <img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg"/> 751 <img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg"/> 752 753 The following figure shows the peak working set (rss) of the allocators 754 on the benchmarks (on the c5.18xlarge instance). 755 756 <img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg"/> 757 <img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg"/> 758 759 760 ## On 24-core AMD Epyc, 2020-01-16 761 762 For completeness, here are the results on a 763 [r5a.12xlarge](https://aws.amazon.com/ec2/instance-types/#Memory_Optimized) instance 764 having a 48 processor AMD Epyc 7000 at 2.5GHz with 384GiB of memory. 765 The results are similar to the Intel results but it is interesting to 766 see the differences in the _larsonN_, _mstressN_, and _xmalloc-testN_ benchmarks. 767 768 <img width="90%" src="doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg"/> 769 <img width="90%" src="doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg"/> 770 771 --> 772 773 774 # References 775 776 - \[1] Emery D. Berger, Kathryn S. McKinley, Robert D. Blumofe, and Paul R. Wilson. 777 _Hoard: A Scalable Memory Allocator for Multithreaded Applications_ 778 the Ninth International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS-IX). Cambridge, MA, November 2000. 779 [pdf](http://www.cs.utexas.edu/users/mckinley/papers/asplos-2000.pdf) 780 781 - \[2] P. Larson and M. Krishnan. _Memory allocation for long-running server applications_. 782 In ISMM, Vancouver, B.C., Canada, 1998. [pdf](http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.45.1947&rep=rep1&type=pdf) 783 784 - \[3] D. Grunwald, B. Zorn, and R. Henderson. 785 _Improving the cache locality of memory allocation_. In R. Cartwright, editor, 786 Proceedings of the Conference on Programming Language Design and Implementation, pages 177–186, New York, NY, USA, June 1993. [pdf](http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.43.6621&rep=rep1&type=pdf) 787 788 - \[4] J. Barnes and P. Hut. _A hierarchical O(n*log(n)) force-calculation algorithm_. Nature, 324:446-449, 1986. 789 790 - \[5] C. Lever, and D. Boreham. _Malloc() Performance in a Multithreaded Linux Environment._ 791 In USENIX Annual Technical Conference, Freenix Session. San Diego, CA. Jun. 2000. 792 Available at <https://github.com/kuszmaul/SuperMalloc/tree/master/tests> 793 794 - \[6] Timothy Crundal. _Reducing Active-False Sharing in TCMalloc_. 2016. CS16S1 project at the Australian National University. [pdf](http://courses.cecs.anu.edu.au/courses/CSPROJECTS/16S1/Reports/Timothy_Crundal_Report.pdf) 795 796 - \[7] Alexey Kukanov, and Michael J Voss. 797 _The Foundations for Scalable Multi-Core Software in Intel Threading Building Blocks._ 798 Intel Technology Journal 11 (4). 2007 799 800 - \[8] Bobby Powers, David Tench, Emery D. Berger, and Andrew McGregor. 801 _Mesh: Compacting Memory Management for C/C++_ 802 In Proceedings of the 40th ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI'19), June 2019, pages 333-–346. 803 804 <!-- 805 - \[9] Paul Liétar, Theodore Butler, Sylvan Clebsch, Sophia Drossopoulou, Juliana Franco, Matthew J Parkinson, 806 Alex Shamis, Christoph M Wintersteiger, and David Chisnall. 807 _Snmalloc: A Message Passing Allocator._ 808 In Proceedings of the 2019 ACM SIGPLAN International Symposium on Memory Management, 122–135. ACM. 2019. 809 --> 810 811 # Contributing 812 813 This project welcomes contributions and suggestions. Most contributions require you to agree to a 814 Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 815 the rights to use your contribution. For details, visit https://cla.microsoft.com. 816 817 When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 818 a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 819 provided by the bot. You will only need to do this once across all repos using our CLA. 820 821 822 # Older Release Notes 823 824 * 2021-11-14, `v1.7.3`, `v2.0.3` (beta): improved WASM support, improved macOS support and performance (including 825 M1), improved performance for v2 for large objects, Python integration improvements, more standard 826 installation directories, various small fixes. 827 * 2021-06-17, `v1.7.2`, `v2.0.2` (beta): support M1, better installation layout on Linux, fix 828 thread_id on Android, prefer 2-6TiB area for aligned allocation to work better on pre-windows 8, various small fixes. 829 * 2021-04-06, `v1.7.1`, `v2.0.1` (beta): fix bug in arena allocation for huge pages, improved aslr on large allocations, initial M1 support (still experimental). 830 * 2021-01-31, `v2.0.0`: beta release 2.0: new slice algorithm for managing internal mimalloc pages. 831 * 2021-01-31, `v1.7.0`: stable release 1.7: support explicit user provided memory regions, more precise statistics, 832 improve macOS overriding, initial support for Apple M1, improved DragonFly support, faster memcpy on Windows, various small fixes. 833 834 * 2020-09-24, `v1.6.7`: stable release 1.6: using standard C atomics, passing tsan testing, improved 835 handling of failing to commit on Windows, add [`mi_process_info`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc.h#L156) api call. 836 * 2020-08-06, `v1.6.4`: stable release 1.6: improved error recovery in low-memory situations, 837 support for IllumOS and Haiku, NUMA support for Vista/XP, improved NUMA detection for AMD Ryzen, ubsan support. 838 * 2020-05-05, `v1.6.3`: stable release 1.6: improved behavior in out-of-memory situations, improved malloc zones on macOS, 839 build PIC static libraries by default, add option to abort on out-of-memory, line buffered statistics. 840 * 2020-04-20, `v1.6.2`: stable release 1.6: fix compilation on Android, MingW, Raspberry, and Conda, 841 stability fix for Windows 7, fix multiple mimalloc instances in one executable, fix `strnlen` overload, 842 fix aligned debug padding. 843 * 2020-02-17, `v1.6.1`: stable release 1.6: minor updates (build with clang-cl, fix alignment issue for small objects). 844 * 2020-02-09, `v1.6.0`: stable release 1.6: fixed potential memory leak, improved overriding 845 and thread local support on FreeBSD, NetBSD, DragonFly, and macOSX. New byte-precise 846 heap block overflow detection in debug mode (besides the double-free detection and free-list 847 corruption detection). Add `nodiscard` attribute to most allocation functions. 848 Enable `MIMALLOC_PAGE_RESET` by default. New reclamation strategy for abandoned heap pages 849 for better memory footprint. 850 * 2020-02-09, `v1.5.0`: stable release 1.5: improved free performance, small bug fixes. 851 * 2020-01-22, `v1.4.0`: stable release 1.4: improved performance for delayed OS page reset, 852 more eager concurrent free, addition of STL allocator, fixed potential memory leak. 853 * 2020-01-15, `v1.3.0`: stable release 1.3: bug fixes, improved randomness and [stronger 854 free list encoding](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396) in secure mode. 855 856 * 2019-12-22, `v1.2.2`: stable release 1.2: minor updates. 857 * 2019-11-22, `v1.2.0`: stable release 1.2: bug fixes, improved secure mode (free list corruption checks, double free mitigation). Improved dynamic overriding on Windows. 858 * 2019-10-07, `v1.1.0`: stable release 1.1. 859 * 2019-09-01, `v1.0.8`: pre-release 8: more robust windows dynamic overriding, initial huge page support. 860 * 2019-08-10, `v1.0.6`: pre-release 6: various performance improvements.