Repository navigation
Releases: amsokol/mimalloc
Release list
v3.6.0
Updates to mimalloc v3.6.0 (upstream release of 2026-10-23, 223 commits after v3.5.3) and adapts mimalloc::Option to it.
[dependencies]
mimalloc = { git = "https://github.com/amsokol/mimalloc", tag = "v3.6.0" }Before you upgrade: what can affect your program
-
Breaking change in this crate: three
mimalloc::Optionvariants were renamed, following upstream. Update the names if you use them:v3.5.3+1 v3.6.0 MIMALLOC_<NAME>Option::GuardedPreciseOption::UnsafeGuardedPreciseunsafe_guarded_preciseOption::MinimalPurgeSizeOption::ArenaPurgeMinSizearena_purge_min_sizeOption::CollectMergesStatsOption::StatsMergeOnCollectstats_merge_on_collectOption::name()returns the new names. Of the old environment variables, onlyMIMALLOC_MINIMAL_PURGE_SIZEis still accepted (mimalloc keeps it as a legacy name);MIMALLOC_GUARDED_PRECISEandMIMALLOC_COLLECT_MERGES_STATSare silently ignored now, so rename them in your deployment.Optionis#[non_exhaustive], andOption::ALLgrew from 39 to 45 entries. -
Cross-thread page reclaim is now on by default (
page_reclaim_on_free: 0 → 1). A thread that frees a block into an abandoned page can now take that page over, even when the page came from another thread. This is upstream's change to improve reuse and speed in multi-threaded programs; it can also change how much memory a program with many short-lived or pooled threads holds.- Since 3.6.0 the option is only a default for new heaps: each heap copies it when it is created. The heap behind the Rust global allocator is created before
main, soOption::PageReclaimOnFree.set(..)frommaindoes not change it. To get the 3.5 behaviour, start the process withMIMALLOC_PAGE_RECLAIM_ON_FREE=0.
- Since 3.6.0 the option is only a default for new heaps: each heap copies it when it is created. The heap behind the Rust global allocator is created before
-
Large freed ranges are now returned to the OS immediately. A freed range of at least
arena_purge_immediate_size(new option, 32 MiB by default, in KiB) is purged as it is freed, whateverpurge_delay × arena_purge_multsays. A program that frees blocks of 32 MiB or more will see its RSS drop at once instead of after about 4 s, and may pay more page faults when it allocates such blocks again. A negativepurge_delaystill never purges.Option::ArenaPurgeImmediateSize.set(..)works frommain(read on every free).collect(force)is unchanged. -
Memory layout of small blocks changed. Upstream now gives blocks a per-page, hashed cache offset for the first block, to spread small allocations over the CPU cache sets (upstream issue #1121), and moves 64 KiB blocks into large pages. The goal is fewer cache conflicts; the side effect is that the usable layout and the RSS of a program can differ somewhat from 3.5.x. Measure with
process_info().current_rssif memory matters to you. -
Transparent huge pages (Linux). Upstream reworked how the huge page size is detected (it now reads
hpage_pmd_size). If the kernel's huge page size is over 8 MiB (for example arm64 with 64 KiB pages), mimalloc now treats the system as having no THP and marks its mappingsMADV_NOHUGEPAGE. On the usual 2 MiB x86-64 setup nothing changes:allow_thpstill defaults to 2,no_thpstill builds withMI_DEFAULT_ALLOW_THP=0, andMIMALLOC_ALLOW_THP=0still overrides it. -
A heap profiler is now compiled in and always available. Upstream built a profiler into mimalloc (
MI_PROFILE, on by default). Upstream says it adds overhead only once it is activated withMIMALLOC_PROFILE=<basename>, which writes pprof snapshots (I did not measure the cost of having it compiled in). Its settings are the newOption::Profile*variants (MIMALLOC_PROFILE_ALLOC_INTERVAL,_INUSE_INTERVAL,_TIME_INTERVAL,_SAMPLE_RATE); the profiler reads them once at process start, so set them with environment variables, not withOption::setfrommain. Upstream also keeps detailed statistics per size bin always on. Limitation of this crate: upstream's CMake build detectsexecinfo.h/libunwindand definesMI_HAS_EXECINFOH; this crate'sbuild.rsdoes not, so on Unix the profiler records samples without call stacks (its backtrace function is a stub returning 0 frames). On Windows it usesCaptureStackBackTrace. I checked on Linux thatMIMALLOC_PROFILEwrites snapshot files; they contain no stacks.
Changes in this crate
-
c_src/mimallocisv3.6.0.build.rsneeded no change:src/static.cstill includes the sources, which upstream moved intosrc/alloc,arena,heap,prim,profileandutil(sooptions.cis nowsrc/util/options.c). -
mimalloc::Optionfollowsmi_option_tof 3.6.0: the three renames above and six new variants:Variant MIMALLOC_<NAME>Default Notes ProfileAllocIntervalprofile_alloc_interval1 GiB bytes allocated between profiler snapshots; 0 disables ProfileInuseIntervalprofile_inuse_interval0 (off) snapshot when in-use bytes grew by this much ProfileTimeIntervalprofile_time_interval0 (off) seconds between snapshots ProfileSampleRateprofile_sample_rate512 KiB profiler sampling rate in bytes StatsMergeThresholdstats_merge_threshold512 KiB merge thread-heap statistics into the heap after this many bytes; 0 disables ArenaPurgeImmediateSizearena_purge_immediate_size32 MiB (in KiB) see point 3; get_size()returns bytesThe four
Profile*options only matter whenMIMALLOC_PROFILEis set, and are read once at process start (use the environment variables).StatsMergeThresholdandArenaPurgeImmediateSizeare read on every use. -
Documentation updated to the 3.6.0 behaviour:
PurgeDelay,ArenaPurgeMult,ArenaPurgeMinSizeandcollectnow mention the immediate purge of large ranges;PageReclaimOnFreestates the new default and thatsetfrommainhas no effect on the global allocator's heap;AllowThpnotes the over-8 MiB huge page case; the README tuning table has rows forArenaPurgeImmediateSizeandPageReclaimOnFree. -
Version:
3.6.0. The+1revision suffix ofv3.5.3+1is dropped, because the upstream version moved. The Rust API otherwise matches v3.5.3+1:MiMalloc,usable_size,process_info,collect, and thesecure,overrideandno_thpfeatures. -
cc:Cargo.tomlstill requirescc = "1.8"(the minimum, so consumers are not forced to a newercc);Cargo.locknow pinscc 1.10.0(was 1.9.0). -
process_info()andcollect()are unchanged. I compared the C implementations ofmi_process_infoandmi_collectwith 3.5.3; they are identical on Unix, macOS and WASI, and the Windows version differs only in a string literal. The table of sources in theProcessInforustdoc still holds. -
Tested on Linux x86-64 in debug and release, and with the
secure,overrideandno_thpfeatures (option names/discriminants againstmi_options_print_out, set/get round trip,process_info, and RSS going back down after freeing 400 MiB), pluscargo clippyandcargo doc. Not tested on Windows, macOS, 32-bit or other targets in this release.
What changed in mimalloc 3.5.3 → 3.6.0 (upstream)
Upstream summary (its readme): "(v3) add initial profiling hooks and default profiler, "always on" detailed statistics per size-bin, and always-on profiling. Initial rust bindings. Better support for large OS page sizes, support a quiescent state based reclamation interface (for CPython), better cache line aware allocation, fix heap visitor where some pages might be skipped, improve fork support, avoid over-allocation for naturally aligned allocations, fix stderr console output for XBox, fix huge allocation rollback, refactor the source and include files, immediately purge very large allocations, fix bcrypt dependency on windows, fix heap-destroy bug when a fresh heap was allocated at the same address (giving a segfault), page_reclaim_on_free is now on by default."
Full list: microsoft/mimalloc@v3.5.3...v3.6.0. The parts below are grouped by what they mean for a user. Items marked (C API) are in mimalloc.h but not wrapped by this crate; items marked (CMake) are upstream build options that this crate's build.rs does not use.
Behaviour and defaults
page_reclaim_on_freeis on by default (cross-thread reclaim on free); the option is now a per-heap creation default. See point 2 above.- Freed ranges of at least 32 MiB are purged immediately (
arena_purge_immediate_size); an explicitmi_arenas_purge()(C API) was added (upstream issue #1422). Purging is also allowed inarena_free(PR #1448). - Options renamed (
guarded_precise→unsafe_guarded_precise,minimal_purge_size→arena_purge_min_size,collect_merges_stats→stats_merge_on_collect), new options for the profiler,stats_merge_thresholdandarena_purge_immediate_size.guarded_sample_ratenow means "guard an object about every N requested bytes" (was "1 out of N allocations"); its default stays 0 and it only matters withMI_GUARDED, which this crate does not enable. - Small blocks get a cache offset based on a hash of the page; large allocations get a cache offset as well; 64 KiB blocks move into large pages (issues #1121; PR #1339).
page_full_retainadapts when cross-thread frees revive full pages. Stat merging between thread heaps and the heap was reworked (a regression from it was fixed).- No over-allocation for naturally aligned requests (PR #1408); the "naturally aligned" condition was relaxed and is checked in debug builds.
- On Windows, stderr output no longer attaches to the parent console.
Profiling and statistics
- Built-in pprof heap profiler (protobuf and text formats), activated by
MIMALLOC_PROFILE, with allocation/in-use/time interval snapshots, a custom allocation-hook API (mimalloc-profile.h), mapped-libr...
v3.5.3+1
Expose mimalloc options and process info to safe Rust; still mimalloc v3.5.3, build dependency cc 1.9
mimalloc::Option: every non-deprecated mimalloc option, withget,set,is_enabled,set_enabled,get_size,nameandOption::ALL; the rustdoc of each says when mimalloc reads itmimalloc::process_info() -> ProcessInfo(time, current/peak RSS, current/peak commit, page faults) andmimalloc::collect(force)no_thpfeature: transparent huge pages off from process start (MI_DEFAULT_ALLOW_THP=0), sinceallow_thpset frommaincannot undo what mimalloc does beforemain- README: API and a tuning section (
purge_delay0 andno_thpfor long-running processes)
Full Changelog: v3.5.3...v3.5.3+1
v3.5.3
Update dependencies to mimalloc v3.5.3; adjust Cargo files and README
Full Changelog: v3.5.2...v3.5.3
v3.5.2
Update dependencies to mimalloc v3.5.2 and cc v1.4.6; adjust Cargo files and README
Full Changelog: v3.5.1...v3.5.2
v2.5.2
Update mimalloc dependency to version 2.5.2 and cc to version 1.4.6 in Cargo.toml and Cargo.lock, and adjust README to reflect the new version. Update submodule reference for mimalloc.
Full Changelog: v2.5.1...v2.5.2
v1.15.2
Update mimalloc to version 1.15.2 and cc to version 1.4.6. Modify README to reflect the new version tags and update Rust bindings documentation accordingly. Ensure compatibility with the latest features and improvements.
Full Changelog: v1.15.1...v1.15.2