| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
| <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"> | |
| <head> | |
| <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | |
| <meta http-equiv="X-UA-Compatible" content="IE=11"/> | |
| <meta name="generator" content="Doxygen 1.18.0"/> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"/> | |
| <title>mi-malloc: Overriding Malloc</title> | |
| <link href="tabs.css" rel="stylesheet" type="text/css"/> | |
| <script type="text/javascript" src="codefolding.js"></script> | |
| <script type="text/javascript" src="clipboard.js"></script> | |
| <link href="navtree.css" rel="stylesheet" type="text/css"/> | |
| <script type="text/javascript" src="navtreedata.js"></script> | |
| <script type="text/javascript" src="navtree.js"></script> | |
| <script type="text/javascript" src="cookie.js"></script> | |
| <link href="search/search.css" rel="stylesheet" type="text/css"/> | |
| <script type="text/javascript" src="search/searchdata.js"></script> | |
| <script type="text/javascript" src="search/search.js"></script> | |
| <link href="doxygen.css" rel="stylesheet" type="text/css" /> | |
| <link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/> | |
| </head> | |
| <body> | |
| <div id="top"><!-- do not remove this div, it is closed by doxygen! --> | |
| <div id="titlearea"> | |
| <table cellspacing="0" cellpadding="0"> | |
| <tbody> | |
| <tr id="projectrow"> | |
| <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td> | |
| <td id="projectalign"> | |
| <div id="projectname">mi-malloc<span id="projectnumber"> 3.5/2.5/1.15</span> | |
| </div> | |
| </td> | |
| <td> <div id="MSearchBox" class="MSearchBoxInactive"> | |
| <span class="left"> | |
| <span id="MSearchSelect" class="search-icon"><span class="search-icon-dropdown"></span></span> | |
| <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"/> | |
| </span><span class="right"> | |
| <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><div id="MSearchCloseImg" class="close-icon"></div></a> | |
| </span> | |
| </div> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| <!-- end header part --> | |
| <!-- Generated by Doxygen 1.18.0 --> | |
| <script type="text/javascript"> | |
| let searchBox = new SearchBox("searchBox", "search/",'.html'); | |
| </script> | |
| <script type="text/javascript"> | |
| document.addEventListener('DOMContentLoaded', codefold.init); | |
| </script> | |
| </div><!-- top --> | |
| <div id="side-nav" class="ui-resizable side-nav-resizable"> | |
| <div id="nav-tree"> | |
| <div id="nav-tree-contents"> | |
| <div id="nav-sync" class="sync"></div> | |
| </div> | |
| </div> | |
| <div id="splitbar" class="ui-resizable-handle"> | |
| </div> | |
| </div> | |
| <script type="text/javascript"> | |
| document.addEventListener('DOMContentLoaded',() => { initNavTree('overrides.html','',''); }); | |
| </script> | |
| <div id="container"> | |
| <div id="doc-content"> | |
| <!-- window showing the filter options --> | |
| <div id="MSearchSelectWindow"> | |
| </div> | |
| <!-- iframe showing the search results (closed by default) --> | |
| <div id="MSearchResultsWindow"> | |
| <div id="MSearchResults"> | |
| <div class="SRPage"> | |
| <div id="SRIndex"> | |
| <div id="SRResults"></div> | |
| <div class="SRStatus" id="Loading">Loading...</div> | |
| <div class="SRStatus" id="Searching">Searching...</div> | |
| <div class="SRStatus" id="NoMatches">No Matches</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div><div class="header"> | |
| <div class="headertitle"><div class="title">Overriding Malloc </div></div> | |
| </div><!--header--> | |
| <div class="contents"> | |
| <div class="textblock"><p>Overriding the standard <span class="tt"><a class="el" href="group__malloc.html" title="The basic allocation interface.">Basic Allocation</a></span> (and <span class="tt">new</span>) can be done either <em>dynamically</em> or <em>statically</em>.</p> | |
| <h2>Dynamic override</h2> | |
| <p>This is the recommended way to override the standard malloc interface.</p> | |
| <h3>Dynamic Override on Linux, BSD</h3> | |
| <p>On these ELF-based systems we preload the mimalloc shared library so all calls to the standard <span class="tt"><a class="el" href="group__malloc.html" title="The basic allocation interface.">Basic Allocation</a></span> interface are resolved to the <em>mimalloc</em> library. </p><div class="fragment"><div class="line">> env LD_PRELOAD=/usr/lib/libmimalloc.so myprogram</div> | |
| </div><!-- fragment --><p>You can set extra environment variables to check that mimalloc is running, like: </p><div class="fragment"><div class="line">> env MIMALLOC_VERBOSE=1 LD_PRELOAD=/usr/lib/libmimalloc.so myprogram</div> | |
| </div><!-- fragment --><p> or run with the debug version to get detailed statistics: </p><div class="fragment"><div class="line">> env MIMALLOC_SHOW_STATS=1 LD_PRELOAD=/usr/lib/libmimalloc-debug.so myprogram</div> | |
| </div><!-- fragment --><h3>Dynamic Override on MacOS</h3> | |
| <p>On macOS we can also preload the mimalloc shared library so all calls to the standard <span class="tt"><a class="el" href="group__malloc.html" title="The basic allocation interface.">Basic Allocation</a></span> interface are resolved to the <em>mimalloc</em> library. </p><div class="fragment"><div class="line">> env DYLD_INSERT_LIBRARIES=/usr/lib/libmimalloc.dylib myprogram</div> | |
| </div><!-- fragment --><p>Note that certain security restrictions may apply when doing this from the <a href="https://stackoverflow.com/questions/43941322/dyld-insert-libraries-ignored-when-calling-application-through-bash">shell</a>.</p> | |
| <h3>Dynamic Override on Windows</h3> | |
| <p><span id="override_on_windows">Dynamically overriding on mimalloc on Windows</span> is robust and has the particular advantage to be able to redirect all malloc/free calls that go through the (dynamic) C runtime allocator, including those from other DLL's or libraries. As it intercepts all allocation calls on a low level, it can be used reliably on large programs that include other 3rd party components. There are four requirements to make the overriding work well:</p> | |
| <ol type="1"> | |
| <li>Use the C-runtime library as a DLL (using the <span class="tt">/MD</span> or <span class="tt">/MDd</span> switch).</li> | |
| <li>Link your program explicitly with the <span class="tt">mimalloc.lib</span> export library for the <span class="tt">mimalloc.dll</span>. (which must be compiled with <span class="tt">-DMI_OVERRIDE=ON</span>, which is the default though). To ensure the <span class="tt">mimalloc.dll</span> is actually loaded at run-time it is easiest to insert some call to the mimalloc API in the <span class="tt">main</span> function, like <span class="tt"><a class="el" href="group__extended.html#gae9ddddcf14a58d0224ef3c8778e5b057" title="Return the mimalloc version.">mi_version()</a></span> (or use the <span class="tt">/include:<a class="el" href="group__extended.html#gae9ddddcf14a58d0224ef3c8778e5b057" title="Return the mimalloc version.">mi_version</a></span> switch on the linker command, or similarly, <span class="tt">#pragma comment(linker, "/include:<a class="el" href="group__extended.html#gae9ddddcf14a58d0224ef3c8778e5b057" title="Return the mimalloc version.">mi_version</a>")</span> in some source file). See the <span class="tt">mimalloc-test-override</span> project for an example on how to use this.</li> | |
| <li>The <span class="tt">mimalloc-redirect.dll</span> must be put in the same directory as the main <span class="tt">mimalloc.dll</span> at runtime (as it is a dependency of that DLL). The redirection DLL ensures that all calls to the C runtime malloc API get redirected to mimalloc functions (which reside in <span class="tt">mimalloc.dll</span>).</li> | |
| <li>Ensure the <span class="tt">mimalloc.dll</span> comes as early as possible in the import list of the final executable (so it can intercept all potential allocations). You can use <span class="tt">minject -l <exe></span> to check this if needed.</li> | |
| </ol> | |
| <p>For best performance on Windows with C++, it is also recommended to also override the <span class="tt">new</span>/<span class="tt">delete</span> operations (by including <a href="https://github.com/microsoft/mimalloc/blob/main/include/mimalloc-new-delet.h"><span class="tt">mimalloc-new-delete.h</span></a> a single(!) source file in your project).</p> | |
| <p>The environment variable <span class="tt">MIMALLOC_DISABLE_REDIRECT=1</span> can be used to disable dynamic overriding at run-time. Use <span class="tt">MIMALLOC_VERBOSE=1</span> to check if mimalloc was successfully redirected.</p> | |
| <p>For different platforms than x64, you may need a specific [redirection dll](bin). Furthermore, we cannot always re-link an executable or ensure <span class="tt">mimalloc.dll</span> comes first in the import table. In such cases the [<span class="tt">minject</span>](bin) tool can be used to patch the executable's import tables.</p> | |
| <h2>Static override</h2> | |
| <p>On Unix-like systems, you can also statically link with <em>mimalloc</em> to override the standard malloc interface. The recommended way is to link the final program with the <em>mimalloc</em> single object file (<span class="tt">mimalloc.o</span>). We use an object file instead of a library file as linkers give preference to that over archives to resolve symbols. To ensure that the standard malloc interface resolves to the <em>mimalloc</em> library, link it as the first object file. For example: </p><div class="fragment"><div class="line">> gcc -o myprogram mimalloc.o myfile1.c ...</div> | |
| </div><!-- fragment --><p>Another way to override statically that works on all platforms, is to link statically to mimalloc (as shown in the introduction) and include a header file in each source file that re-defines <span class="tt"><a class="el" href="group__malloc.html" title="The basic allocation interface.">Basic Allocation</a></span> etc. to <span class="tt"><a class="el" href="group__malloc.html#gae1dd97b542420c87ae085e822b1229e8" title="Allocate size bytes.">mi_malloc</a></span>. This is provided by <a href="https://github.com/microsoft/mimalloc/blob/main/include/mimalloc-override.h"><span class="tt">mimalloc-override.h</span></a>. This only works reliably though if all sources are under your control or otherwise mixing of pointers from different heaps may occur!</p> | |
| <h2>List of Overrides:</h2> | |
| <p>The specific functions that get redirected to the <em>mimalloc</em> library are:</p> | |
| <div class="fragment"><div class="line"><span class="comment">// C</span></div> | |
| <div class="line"><span class="keywordtype">void</span>* malloc(<span class="keywordtype">size_t</span> size);</div> | |
| <div class="line"><span class="keywordtype">void</span>* calloc(<span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> n);</div> | |
| <div class="line"><span class="keywordtype">void</span>* realloc(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div> | |
| <div class="line"><span class="keywordtype">void</span> free(<span class="keywordtype">void</span>* p);</div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="keywordtype">void</span>* aligned_alloc(<span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size);</div> | |
| <div class="line"><span class="keywordtype">char</span>* strdup(<span class="keyword">const</span> <span class="keywordtype">char</span>* s);</div> | |
| <div class="line"><span class="keywordtype">char</span>* strndup(<span class="keyword">const</span> <span class="keywordtype">char</span>* s, <span class="keywordtype">size_t</span> n);</div> | |
| <div class="line"><span class="keywordtype">char</span>* realpath(<span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">char</span>* resolved_name);</div> | |
| <div class="line"> </div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="comment">// C++</span></div> | |
| <div class="line"><span class="keywordtype">void</span> <span class="keyword">operator</span> <span class="keyword">delete</span>(<span class="keywordtype">void</span>* p);</div> | |
| <div class="line"><span class="keywordtype">void</span> <span class="keyword">operator</span> <span class="keyword">delete</span>[](<span class="keywordtype">void</span>* p);</div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>(std::size_t n) <span class="keyword">noexcept</span>(<span class="keyword">false</span>);</div> | |
| <div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>[](std::size_t n) <span class="keyword">noexcept</span>(<span class="keyword">false</span>);</div> | |
| <div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>( std::size_t n, std::align_val_t align) <span class="keyword">noexcept</span>(<span class="keyword">false</span>);</div> | |
| <div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>[]( std::size_t n, std::align_val_t align) <span class="keyword">noexcept</span>(<span class="keyword">false</span>);</div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span> ( std::size_t count, <span class="keyword">const</span> std::nothrow_t& tag);</div> | |
| <div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>[]( std::size_t count, <span class="keyword">const</span> std::nothrow_t& tag);</div> | |
| <div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span> ( std::size_t count, std::align_val_t al, <span class="keyword">const</span> std::nothrow_t&);</div> | |
| <div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>[]( std::size_t count, std::align_val_t al, <span class="keyword">const</span> std::nothrow_t&);</div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="comment">// Posix</span></div> | |
| <div class="line"><span class="keywordtype">int</span> posix_memalign(<span class="keywordtype">void</span>** p, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size);</div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="comment">// Linux</span></div> | |
| <div class="line"><span class="keywordtype">void</span>* memalign(<span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size);</div> | |
| <div class="line"><span class="keywordtype">void</span>* valloc(<span class="keywordtype">size_t</span> size);</div> | |
| <div class="line"><span class="keywordtype">void</span>* pvalloc(<span class="keywordtype">size_t</span> size);</div> | |
| <div class="line"><span class="keywordtype">size_t</span> malloc_usable_size(<span class="keywordtype">void</span> *p);</div> | |
| <div class="line"><span class="keywordtype">void</span>* reallocf(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="comment">// macOS</span></div> | |
| <div class="line"><span class="keywordtype">void</span> vfree(<span class="keywordtype">void</span>* p);</div> | |
| <div class="line"><span class="keywordtype">size_t</span> malloc_size(<span class="keyword">const</span> <span class="keywordtype">void</span>* p);</div> | |
| <div class="line"><span class="keywordtype">size_t</span> malloc_good_size(<span class="keywordtype">size_t</span> size);</div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="comment">// BSD</span></div> | |
| <div class="line"><span class="keywordtype">void</span>* reallocarray( <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size );</div> | |
| <div class="line"><span class="keywordtype">void</span>* reallocf(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div> | |
| <div class="line"><span class="keywordtype">void</span> cfree(<span class="keywordtype">void</span>* p);</div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="comment">// NetBSD</span></div> | |
| <div class="line"><span class="keywordtype">int</span> reallocarr(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="comment">// Windows</span></div> | |
| <div class="line"><span class="keywordtype">void</span>* _expand(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div> | |
| <div class="line"><span class="keywordtype">size_t</span> _msize(<span class="keywordtype">void</span>* p);</div> | |
| <div class="line"> </div> | |
| <div class="line"><span class="keywordtype">void</span>* _malloc_dbg(<span class="keywordtype">size_t</span> size, <span class="keywordtype">int</span> block_type, <span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">int</span> line);</div> | |
| <div class="line"><span class="keywordtype">void</span>* _realloc_dbg(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize, <span class="keywordtype">int</span> block_type, <span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">int</span> line);</div> | |
| <div class="line"><span class="keywordtype">void</span>* _calloc_dbg(<span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size, <span class="keywordtype">int</span> block_type, <span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">int</span> line);</div> | |
| <div class="line"><span class="keywordtype">void</span>* _expand_dbg(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> size, <span class="keywordtype">int</span> block_type, <span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">int</span> line);</div> | |
| <div class="line"><span class="keywordtype">size_t</span> _msize_dbg(<span class="keywordtype">void</span>* p, <span class="keywordtype">int</span> block_type);</div> | |
| <div class="line"><span class="keywordtype">void</span> _free_dbg(<span class="keywordtype">void</span>* p, <span class="keywordtype">int</span> block_type);</div> | |
| </div><!-- fragment --> </div></div><!-- contents --> | |
| </div><!-- PageDoc --> | |
| </div><!-- doc-content --> | |
| </div><!-- container --> | |
| <!-- start footer part --> | |
| <div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> | |
| <ul> | |
| <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.18.0 </li> | |
| </ul> | |
| </div> | |
| </body> | |
| </html> |