/ source / mimalloc / readme.md
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  &nbsp;
  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&times; 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&times; 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&times; 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&times; 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&times;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.