0

0

c++怎么使用std::pmr来管理内存资源_C++内存资源管理与多态分配器实践

穿越時空

穿越時空

发布时间:2025-11-11 13:59:02

|

560人浏览过

|

来源于php中文网

原创

std::pmr通过memory_resource实现灵活内存管理,支持多态分配器与多种内置资源,如monotonic_buffer_resource用于高效批量分配,synchronized_pool_resource适用于多线程内存池,开发者亦可自定义resource记录分配行为,结合pmr容器实现高性能、可维护的内存控制,关键在于按场景选择资源并妥善管理生命周期。

c++怎么使用std::pmr来管理内存资源_c++内存资源管理与多态分配器实践

在现代C++开发中,高效、灵活的内存管理是提升性能和可维护性的关键。C++17引入了std::pmr(Polymorphic Memory Resource,多态内存资源),为开发者提供了一种统一且可扩展的内存分配机制。它基于std::memory_resource抽象接口,允许运行时动态切换不同的内存分配策略,而无需修改使用分配器的代码。

理解 std::pmr 的核心组件

std::pmr 的设计围绕几个核心类型展开:

  • std::pmr::memory_resource:抽象基类,定义了do_allocatedo_deallocate等虚函数,用于实现具体的内存分配逻辑。
  • std::pmr::polymorphic_allocator:模板分配器,持有指向memory_resource的指针,通过该资源进行内存分配。
  • 派生自 memory_resource 的具体资源类型:如std::pmr::synchronized_pool_resourcestd::pmr::unsynchronized_pool_resourcestd::pmr::monotonic_buffer_resource等,提供不同行为的内存池或缓冲区管理。

所有std::pmr容器(如std::pmr::vectorstd::pmr::string)都接受polymorphic_allocator作为模板参数,从而将内存分配委托给指定的资源。

使用内置内存资源进行高效分配

最常见的实践是利用标准库提供的内存资源来优化特定场景下的性能。例如,在频繁创建小对象的场景中,使用内存池可以显著减少系统调用开销。

立即学习C++免费学习笔记(深入)”;

下面是一个使用monotonic_buffer_resource的例子,它适合于“批量分配、一次性释放”的模式:

#include 
#include 
#include 

int main() { // 创建一块本地缓冲区 char buffer[1024]; // 基于缓冲区构建单调资源(先入先出分配) std::pmr::monotonic_buffer_resource pool{buffer, sizeof(buffer)};

// 使用该资源创建 polymorphic_allocator
std::pmr::polymorphic_allocatorzuojiankuohaophpcnintyoujiankuohaophpcn alloc{&pool};

// 构造一个使用该分配器的 vector
std::pmr::vectorzuojiankuohaophpcnintyoujiankuohaophpcn vec{alloc};
for (int i = 0; i zuojiankuohaophpcn 100; ++i) {
    vec.push_back(i);
}

std::cout zuojiankuohaophpcnzuojiankuohaophpcn "Size: " zuojiankuohaophpcnzuojiankuohaophpcn vec.size() zuojiankuohaophpcnzuojiankuohaophpcn "\n";

// 当 pool 超出作用域时,所有通过它分配的内存自动释放
return 0;

}

在这个例子中,所有vec内部节点的分配都由pool完成。由于monotonic_buffer_resource只是移动指针,分配速度极快,且析构时整体回收,避免了逐个free的开销。

讯飞听见会议
讯飞听见会议

科大讯飞推出的AI智能会议系统

下载

构建自定义 memory_resource 实现特殊需求

对于更复杂的场景,你可以继承memory_resource并实现自己的分配逻辑。比如,你想记录所有内存分配行为:

struct logging_resource : std::pmr::memory_resource {
    void* do_allocate(std::size_t bytes, std::size_t alignment) override {
        void* ptr = std::malloc(bytes); // 简单起见仍用 malloc
        if (!ptr) throw std::bad_alloc{};
        std::cout << "Allocated " << bytes << " bytes at " << ptr << "\n";
        return ptr;
    }
void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override {
    std::cout zuojiankuohaophpcnzuojiankuohaophpcn "Deallocated " zuojiankuohaophpcnzuojiankuohaophpcn bytes zuojiankuohaophpcnzuojiankuohaophpcn " bytes at " zuojiankuohaophpcnzuojiankuohaophpcn p zuojiankuohaophpcnzuojiankuohaophpcn "\n";
    std::free(p);
}

bool do_is_equal(const memory_resource& other) const noexcept override {
    return this == &other;
}

};

然后将其用于任意std::pmr容器:

logging_resource log_res;
std::pmr::vector logged_vec{std::pmr::polymorphic_allocator{&log_res}};
logged_vec.resize(10);
// 输出每一步的分配/释放日志

共享与传递 memory_resource 的最佳实践

实际项目中,通常会将memory_resource作为上下文的一部分进行传递。推荐做法是:

  • 在系统初始化时创建长期存在的资源实例(如全局池)。
  • 通过构造函数或工厂函数将memory_resource*注入需要高性能分配的模块。
  • 优先使用synchronized_pool_resource在多线程环境中,除非能保证单线程访问。
  • 避免频繁切换资源,因为每个容器持有的分配器绑定到特定资源。

例如,游戏引擎可能为每个帧创建一个monotonic_buffer_resource,供当帧所有临时对象使用,帧结束时统一重置,极大提升性能。

基本上就这些。std::pmr 提供了强大而灵活的内存管理能力,合理使用可以在不牺牲代码清晰度的前提下,显著提升程序效率。关键是根据场景选择合适的资源类型,并保持资源生命周期的清晰管理。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

312

2023.08.02

resource是什么文件
resource是什么文件

Resource文件是一种特殊类型的文件,它通常用于存储应用程序或操作系统中的各种资源信息。它们在应用程序开发中起着关键作用,并在跨平台开发和国际化方面提供支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

140

2023.12.20

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

14

2025.11.27

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

989

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

50

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

195

2025.12.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

469

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

106

2025.12.24

vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

28

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号