std::pmr::monotonic_buffer_resource 是 C++17 提供的单向不可回收内存池分配器,适用于短生命周期、大量小对象且无需单独释放的场景;其分配极快、零碎片,但仅在析构时批量释放内存,不支持单个对象回收。

std::pmr::monotonic_buffer_resource 是 C++17 引入的 std::pmr(polymorphic memory resource)体系中一个**单向、不可回收的内存池分配器**,常被通俗称为“单调缓冲资源”或“竞技场式分配器”。它不释放中间分配的内存,只在析构时一次性归还全部内存,因此特别适合**短生命周期、大量小对象、且无需单独释放的场景**(如一帧渲染、一次网络请求处理、一次算法遍历)。
核心特性:快 + 简 + 不回收
它底层通常基于一块预分配的大缓冲区(可由用户传入,也可内部动态申请),所有 allocate() 请求都在该缓冲区内线性推进指针,类似栈式分配:
- 分配极快 —— 几乎只是指针加法 + 对齐调整,无查找、无锁、无元数据管理
- 零碎片 —— 内存按顺序使用,不会因反复分配/释放产生空洞
- 不可释放单个对象 ——
deallocate()被忽略(或仅校验),真正释放只发生在整个 resource 析构时 - 无线程安全保证 —— 默认非线程安全;多线程需自行加锁或每个线程独享一个实例
典型高性能用法:配合 std::pmr::vector / string 等容器
不是直接 new/delete,而是让标准容器通过 std::pmr::polymorphic_allocator 绑定到 monotonic_buffer_resource 上:
#include#include #include std::pmr::monotonic_buffer_resource pool{1024 * 1024}; // 预分配 1MB std::pmr::polymorphic_allocator
alloc{&pool}; // 所有 vector 内部内存都从 pool 分配 std::pmr::vector
v{alloc}; v.reserve(10000); for (int i = 0; i < 10000; ++i) v.push_back(i); // 字符串同理 std::pmr::string s{"hello world", alloc};
当 pool 离开作用域,整块 1MB 内存才被统一释放 —— 避免了成千次 malloc/free 的系统调用开销。
立即学习“C++免费学习笔记(深入)”;
性能关键点:缓冲区大小与复用策略
实际性能高度依赖你如何管理缓冲区:
- 缓冲太小 → 频繁 fallback 到上游 resource(如
std::pmr::new_delete_resource),失去优势 - 缓冲太大 → 浪费内存,尤其在小任务中
- 推荐做法:对固定模式任务(如每帧处理约 50KB 临时数据),预估峰值并略留余量;或用
std::pmr::synchronized_pool_resource替代,需要部分释放能力时再考虑 - 避免跨作用域传递 —— 单调资源不是为长期持有设计的,别把它塞进全局或长生命周期对象里
和 “竞技场(arena)分配器” 的关系
它就是 C++ 标准化的轻量级 arena 分配器:语义上完全符合 arena 的定义 —— 一批对象共享同一片内存区域,批量构造/销毁。但它比某些手动 arena 实现更严格(不支持 reset 中间状态),也比通用 pool 更简单高效。如果你以前用过 Google’s absl::InlinedVector 或 Rust 的 Box::leak+arena,它的思路是相通的。
基本上就这些 —— 不复杂但容易忽略的是:它不是万能加速器,而是一个有明确适用边界的工具。用对了,分配开销趋近于零;用错了,反而增加内存压力或掩盖泄漏。











