130

我正在阅读一本关于内存作为编程概念的书。在后面的一章中,作者大量使用了arena一词,但从未对其进行定义。我搜索了这个词的含义以及它与记忆的关系,但一无所获。以下是作者使用该术语的一些上下文:

“下一个序列化示例包含一种称为从特定领域分配内存的策略。”

“......这在处理内存泄漏或从特定领域分配时很有用。”

“......如果我们想释放内存,那么我们将释放整个arena。”

作者在一章中使用了这个词超过 100 次。词汇表中的唯一定义是:

从 arena 分配- 首先分配一个 arena,然后由程序本身(而不是由进程内存管理器)管理 arena 内的分配/解除分配的技术;用于复杂数据结构和对象的压缩和序列化,或用于管理安全关键和/或容错系统中的内存。

鉴于这些情况,谁能为我定义竞技场?

4

4 回答 4

143

竞技场只是一块大的、连续的内存,您分配一次,然后通过分发部分内存来手动管理内存。例如:

char * arena = malloc(HUGE_NUMBER);

unsigned int current = 0;

void * my_malloc(size_t n) { current += n; return arena + current - n; }

关键是您可以完全控制内存分配的工作方式。唯一不受您控制的是初始分配的单个库调用。

一个流行的用例是每个 arena 仅用于分配一个固定大小的内存块。在这种情况下,您可以编写非常有效的回收算法。另一个用例是每个“任务”有一个竞技场,当您完成任务后,您可以一次性释放整个竞技场,而无需担心跟踪单个释放。

这些技术中的每一个都非常专业,并且通常只有在您确切知道自己在做什么以及为什么正常的库分配不够好时才会派上用场。请注意,一个好的内存分配器本身已经可以发挥很多作用,在您开始自己处理内存之前,您需要大量证据证明这还不够好。

于 2012-10-10T17:43:00.260 回答
13

我会用这个作为可能的答案。

•Memory Arena (also known as break space)--the area where dynamic runtime memory is stored. The memory arena consists of the heap and unused memory. The heap is where all user-allocated memory is located. The heap grows up from a lower memory address to a higher memory address.

我将添加Wikipedia 的同义词:region、zone、arena、area 或 memory context。

基本上它是您从操作系统获得的内存,然后分配出去,然后可以一次全部释放。这样做的好处是重复的小调用malloc()可能代价高昂(每次内存分配都有性能成本:在程序的逻辑地址空间中分配内存所花费的时间以及将该地址空间分配给物理内存所花费的时间)就好像您知道一个球场一样,您可以为自己获得一大块内存,然后根据需要/如何将其分配给您的变量。

于 2012-10-10T17:41:37.123 回答
8

将其视为“堆”的同义词。通常,您的进程只有一个堆/竞技场,所有内存分配都从那里发生。

但是,有时您会遇到将一系列分配组合在一起的情况(例如,为了性能,避免碎片等)。在这种情况下,最好分配一个新的堆/竞技场,然后对于任何分配,您可以决定从哪个堆分配。

例如,您可能有一个粒子系统,其中经常分配和释放大量相同大小的对象。为避免内存碎片,您可以从仅用于这些粒子的堆中分配每个粒子,所有其他分配将来自默认堆。

于 2012-10-10T17:43:04.060 回答
6

来自http://www.bozemanpass.com/info/linux/malloc/Linux_Heap_Contention.html

libc.so.x 共享库包含 glibc 组件,堆代码位于其中。堆的当前实现使用多个独立的子堆,称为 arenas。每个 arena 都有自己的互斥锁用于并发保护。因此,如果一个进程的堆中有足够的区域,并且有一种机制可以在它们之间平均分配线程的堆访问,那么对互斥体的争用可能性应该是最小的。事实证明,这对分配很有效。在 malloc() 中,进行测试以查看当前线程的当前目标 arena 的互斥锁是否空闲(trylock)。如果是这样,那么竞技场现在被锁定并且分配继续进行。如果互斥体忙,则依次尝试每个剩余的竞技场并在互斥体不忙时使用。如果没有任何竞技场可以在没有阻塞的情况下被锁定,则会创建一个新的竞技场。根据定义,该区域尚未锁定,因此分配现在可以继续进行而不会阻塞。最后,线程最后一次使用的 arena 的 ID 保留在线程本地存储中,随后用作该线程下一次调用 malloc() 时尝试的第一个 arena。因此,所有对 malloc() 的调用都将继续进行而不会阻塞。

你也可以参考这个链接:

http://www.codeproject.com/Articles/44850/Arena-Allocator-DTOR-and-Embedded-Preallocated-Buf

于 2012-10-10T17:43:37.617 回答