Faithful, performant tracking of committed memory and limit enforcement
维护者通常 5 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 42/100
- Issue 类型
- 功能
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- c, linux
调研方向
先阅读 mi_os_decommit_ex、_mi_prim_decommit、_mi_prim_commit、mi_arena_purge 和 mi_arena_try_alloc_at 周围的 Linux 路径。检查提议的 needs_recommit 行为和 mi_register_rss_callbacks API,以及报告的 benchmark 结果。在开始实现之前,维护者就准确的 committed-memory 记账方式和成对的限制执行回调达成一致,即视为完成。
由索引模型根据 Issue 内容生成。
描述
Problem statement: We want to use mimalloc for an analytical database on Linux. We deploy the database in Kubernetes pods with a memory limit. If the process requests more memory than this limit, Kubernetes kills it. We want to avoid those out-of-memory kills and instead gracefully recover inside our database server.
Potential solution: To avoid our process getting killed, we want to track the amount of memory held by the process and fail allocations before requesting more memory from the operating system when the process is close to its limit.
At a high level, we need:
- mimalloc to provide an accurate measure of its OS-backed memory and
- a way for the embedding application to keep that measure below a limit.
Towards those goals, we propose two independent changes:
- a mode in which committed follows physical memory with performance being on par with stock mimalloc
- and paired callbacks through which the application can reject increases and observe decreases.
We have an in-house prototype of those changes, described in more detail below. We are happy to contribute those changes upstream, but before opening PRs would appreciate your feedback on our design thoughts. We would also be interested in any existing alternatives, prior discussions, configuration knobs, etc. which we may have missed.
Keeping committed aligned with RSS
We would like to use mimalloc's committed-memory statistic to track our RSS.
We measured our database on TPC-DS SF1000 using mimalloc 3.4.1 with MIMALLOC_ARENA_EAGER_COMMIT=0.
In a normal release build, the mimalloc committed counter (green) behaves like a high-water mark instead of following the process RSS (black).
This happens because mi_os_decommit_ex subtracts from committed only when _mi_prim_decommit returns needs_recommit == true. In a normal Linux release build, _mi_prim_decommit releases the physical pages with madvise(MADV_DONTNEED) but returns needs_recommit == false. mi_arena_purge therefore retains the slices_committed bits, and a later allocation in mi_arena_try_alloc_at call _mi_os_reuse instead of _mi_os_commit_ex.
The existing Linux implementation sets needs_recommit to true when mimalloc is built with MI_SECURE > 2. We repeated the same benchmark and runtime configuration with mimalloc built using MI_SECURE=4 and MI_FREE_IS_CHECKED=1. In this build, committed closely tracks RSS.
In those builds, mimalloc's committed-memory statistic closely tracks RSS.
However, it comes at a high performance cost. _mi_prim_decommit calls mprotect(PROT_NONE), and _mi_prim_commit later calls mprotect(PROT_READ|PROT_WRITE). These calls update the protection attributes of the affected Linux virtual memory areas (VMAs) and the corresponding page-table entries on every purge and recommit cycle. The full sequential benchmark recorded about 2.3 million additional mprotect calls, and the peak VMA count increased from 16,472 to 49,781. In a separate targeted benchmark, this led to a median runtime increase from 284s to 292 seconds, by 8s, i.e. 2.7%.
We want mimalloc's committed-memory statistic to closely track RSS, but don't want to pay this performance penalty.
We therefore propose a configuration that provides faithful committed-memory accounting without the overhead of calling mprotect. Our prototype always sets needs_recommit to true but omits the mprotect calls.
Enforcing a limit on committed memory
The embedding application needs to enforce a limit against the same accounting. We propose paired callbacks around changes to committed. Our prototype adds mi_commit_callback_fun(size_t bytes, void* arg) and mi_decommit_callback_fun(size_t bytes, void* arg), registered together through mi_register_rss_callbacks.
Before every increase to committed, the commit callback atomically reserves the corresponding number of bytes. If it returns false, mimalloc abandons the attempted increase and reports the allocation as failed. After every decrease to committed, the decommit callback releases those bytes. Bracketing every change to committed this way allows the application to maintain a race-free atomic counter across allocator threads.
- 主要语言
- C
- 星标
- 13.4k
- 派生
- 1.2k
- 平均合并
- 4 天 8 小时
- 30 天内合并 PR
- 8
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
microsoft/mimalloc 的其他 Issue
-
stale
难度 2/5 1-3 小时 新手友好度 74/100
microsoft/mimalloc#1113 · 1 条评论 ·
维护者通常 5 天内回复
-
难度 2/5 1-3 小时 新手友好度 65/100
microsoft/mimalloc#886 · 4 条评论 · 1 个 reaction ·
维护者通常 5 天内回复
-
难度 2/5 1-3 小时 新手友好度 64/100
microsoft/mimalloc#368 · 1 条评论 ·
维护者通常 5 天内回复
-
Intermittent SIGSEGV / memory corruption under WSL2 with mimalloc 3.3.2 as Rust global allocator未关闭
难度 5/5 一周以上 新手友好度 8/100
维护者通常 5 天内回复
-
难度 5/5 一周以上 新手友好度 35/100
microsoft/mimalloc#1405 · 2 条评论 · 2 个 reaction ·
维护者通常 5 天内回复
查看 microsoft/mimalloc 的全部 Issue
相似的 Issue
-
native-cpu: -Wreturn-type in skainet_row_threads.c:150 (worker fn has no return)可能已有人在做 @Doomguy-BFG9000 今天认领。 未关闭good first issue size:xs skill:native
难度 1/5 1 小时以内 新手友好度 78/100
SKaiNET-developers/SKaiNET#1358 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 64/100
libsdl-org/SDL#16539 ·
维护者通常 1 天内回复
-
git-workflow task-4
难度 2/5 1-3 小时 新手友好度 66/100
-
bug
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 67/100
dosemu2/dosemu2#3178 · 1 条评论 · 1 个 reaction ·
维护者通常 1 天内回复