内存管理需要解决的问题
-
cache亲和
cache亲和对于高性能应用尤为重要,离散的内存访问,会导致cpu cache失效,不断的从RAM获取数据和剔除数据出cpu cahe,造成严重的性能问题
cache亲和需要提高返回内存局部性
-
分配局部性高
对于不同的容器和对象,需要有不同的分配器
单单使用全局内存分配器是不足的
因为相同类型的对象,它们往往会频繁的一起访问
-
减少内存碎片
内存离散的分配和离散的回收,内存中会出现很多小内存块,导致大内存块无法被申请
通过管理合并这些连续的小内存块,可以有效的缓解内存碎片的问题
-
减少内存扩散
内存离散的分配,可能导致连续访问的内存出现随机的离散,cpu cache无法发挥提速的效果
通过针对不同的数据结构提供个性化的内存分配策略,可以有效的解决扩散问题
-
线程安全分配
对象的内存分配,需要考虑内存安全问题
如果在确定对象的内存申请和释放都是在一个线程内完成
那么可以不需要加锁来管理内存
如果对象的内存申请和释放是跨线程的,那么必要的同步手段是必须的
C++17 pmr内存局部分配器
pmr提供以下三种内存分配策略
monotonic buffer
多次申请,一次释放
monotonic通过多次申请多个连续的内存块提供给容器或者对象
每次申请时,只提供未被分配过的内区片段
已经分配过和被回收到buffer的内存,不会被再次分配出去
在pmr数据结构析构时,一次性,把所有内存释放
它是非线程安全的
比较浪费内存
但是提供非常高的性能
和提供非常高的局部性
unsynchronized pool
通过slab来管理内存块
回收后的内存可以再次分配出去
非线程安全
高性能
局部性不如monotonic
节省内存
pmr析构时,归还内存
synchronized pool
与unsynchronized pool类似
但它是线程安全的
C++17 前的内存局部分配器
- 对于特定对象的分配器,可以通过重载new和delete实现
- 对于stl容器,可以通过实现自定义的allocator来实现
网友评论