http://www.ibm.com/developerworks/cn/linux/l-memory/
基于 UNIX 的系统有两个可映射到附加内存中的基本系统调用:
- brk:
brk()
是一个非常简单的系统调用。 还记得系统中断点吗?该位置是进程映射的内存边界。brk()
只是简单地 将这个位置向前或者向后移动,就可以向进程添加内存或者从进程取走内存。 - mmap:
mmap()
,或者说是“内存映像”,类似于brk()
,但是更为灵活。首先,它可以映射任何位置的内存, 而不单单只局限于进程。其次,它不仅可以将虚拟地址映射到物理的 RAM 或者 swap,它还可以将 它们映射到文件和文件位置,这样,读写内存将对文件中的数据进行读写。不过,在这里,我们只关心mmap
向进程添加被映射的内存的能力。munmap()
所做的事情与mmap()
相反。
在设计一个分配程序时, 要面临许多需要折衷的选择,其中包括:
- 分配的速度。
- 回收的速度。
- 有线程的环境的行为。
- 内存将要被用光时的行为。
- 局部缓存。
- 簿记(Bookkeeping)内存开销。
- 虚拟内存环境中的行为。
- 小的或者大的对象。
- 实时保证。
使用池式内存分配的益处如下所示:
- 应用程序可以简单地管理内存。
- 内存分配和回收更快,因为每次都是在一个池中完成的。分配可以在 O(1) 时间内完成,释放内存池所需时间也差不多(实际上是 O(n) 时间,不过在大部分情况下会除以一个大的因数,使其变成 O(1))。
- 可以预先分配错误处理池(Error-handling pools),以便程序在常规内存被耗尽时仍可以恢复。
- 有非常易于使用的标准实现。
池式内存的缺点是:
- 内存池只适用于操作可以分阶段的程序。
- 内存池通常不能与第三方库很好地合作。
- 如果程序的结构发生变化,则不得不修改内存池,这可能会导致内存管理系统的重新设计。
- 您必须记住需要从哪个池进行分配。另外,如果在这里出错,就很难捕获该内存池。