c++内存分配区(Arena),内存池
在 C++ 中,内存分配区(Arena)通常指的是。Arena 内存管理可以。这种方法的主要目的是。
C++中内存池和内存分配区Arena概念详解_C 语言_脚本之家
大白话解析LevelDB:Arena内存分配器_arena 内存分配器-CSDN博客
在 C++ 中,内存分配区(Arena)通常指的是预先分配的一大块连续内存空间。这种方法的主要目的是提高内存分配和释放的效率,特别是在频繁创建和销毁小对象的场景中。Arena 内存管理可以减少内存碎片,提高缓存一致性,并降低操作系统内存分配器的开销。
有几个开源库提供了 Arena 风格的内存分配功能:
- Google Protobuf:Google 的 Protocol Buffers(Protobuf)库使用了内存分配区来管理序列化数据结构的内存。Protobuf 提供了一个
Arena
类,用于高效地分配和管理 Protobuf 对象的内存。 - jemalloc:虽然 jemalloc 本身是一个通用的内存分配器,它提供了 Arena 的概念,允许更细粒度的内存控制。
- tcmalloc:由 Google 开发的另一款内存分配器,它同样提供了类似 Arena 的功能。
- Boost.Pool:Boost 库中的 Boost.Pool 提供了一个内存池的实现,它允许快速分配和回收固定大小的内存块。
- folly::Memory:Facebook 的开源库 Folly 提供了
folly::Memory
,它包含了一系列内存管理工具,包括 Arena 分配器。
. 使用arena 地址向操作系统申请内存,大小决定了可分配用户内存上限。
2>. 位图 bitmap 为每个对象提供 4bit 标记位,用以保存指针、GC 标记等信息。
3>. 创建 span 时,按页填充对应 spans 空间。在回收 object 时,只需将其地址按页对齐后就可找到所属 span。分配器还用此访问相邻 span,做合并操作。
arena
arena区域就是我们通常说的heap, go从heap分配的内存都在这个区域中.
Arena
大多数C++相关的开源项目都会实现自己的内存管理,而不直接使用标准库的malloc。 现在流行的malloc实现有jemalloc、tcmalloc、ptmalloc等,它们都能高效的管理内存,减少内存碎片,提高多线程下内存分配的性能。但这都是对应于general的应用场景,每个应用都有不同的场景,有的分配大内存为主,有的分配小内存为主。为了更进一步的提高内存分配效率与减少内存碎片,LevelDB使用自己的内存管理机制,Arena。
相比于直接使用malloc,Arena的优势在于:
小内存分配的效率:LevelDB经常需要分配小块内存。对于每个小分配使用malloc可能因为开销而效率不高。“Arena”一次性分配较大的内存块,然后高效地分割出小段。这减少了许多小malloc调用的开销。 这种批处理机制同样应用于jemalloc, tcmalloc等,但他们需要维护复杂的数据结构,不如“Arena”简单高效。
方便统计内存使用情况:LevelDB需要跟踪内存使用情况,通过Arena而不是直接malloc可以方便的记录内存使用情况。
控制内存生命周期:“Arena”允许LevelDB轻松控制其内存分配的生命周期。当Arena被销毁时,它分配的所有内存都在一次操作中被释放,这比单独释放每个块更有效。
我们来看下class Arena的结构:
Glibc中的内存池-ptmalloc
内存池的实现有很多方法,比如google的tcmalloc,我们这里主要讲大家平时最常用的一种:glibc中的ptmalloc。
多线程时代
如果所有的线程都是从同一个地方分配内存,资源的竞争就会非常的激烈,性能就会特别差。
arena的个数限制
arena的个数也不是无限制的,也是有限制的。它受arena_max的变量限制。当arena个数没到达限制时,当前线程没有空闲可用的arena,则会直接创建一个新的arena。
arena_max受进程所在服务器的cpu个数和系统字大小因素影响。
总结
本文讲了malloc申请内存是从ptmalloc的arena中申请的,main_arena全局只有一个,not_main_arena有很多个,讲了arena是怎么的创建的,main_arena和not_main_arena结构上还是有一些区别,但是从使用的角度来看main_arena和not_main_arena是没多大区别;但是到此还是没有申请出一块有效的内存,这块内存又是长啥样的?下一篇文章来揭开这个谜团:malloc_chunk。
更多推荐
所有评论(0)