C指针原理(84)-内存管理与控制

多个内存块(Chunks)通常具有相同的尺寸,从内存块边界地址开始,多个领域( Arena)将众多内存块分割成较小的空间进行分配,超大的内存分配(huge arena)要同时占据多个连续内存块(Chunks)才够用。

麦好的AI乐园博客所有内容是原创,如果转载请注明来源

http://blog.csdn.net/myhaspl/


C指针原理(84)-内存管理与控制_第1张图片

分配大小分为3个部分:小的、大的和巨大的,所有分配请求被安排到最接近的大小边界,超大的内存分配大于内存块的一半,这种分配存储在单独的红黑树中。对小型和大型的分配,块分割成页,使用二伙伴(Binary-Buddy)算法作为分割算法,Binary-Buddy在分配内存的时候,首先找到一个空闲内存块,接着把内存块不断的进行对半切分(切分得到的2个同样大小的内存块互为伙伴),直到切出来的内存块刚好满足分配需求为止,合并的时候,只有伙伴才能合并为一个新的内存块。

小型和大型分配通过反复将分配大小折半,最后走到一个内存页,但只能合并的方式是分裂过程的相反操作,运行的状态信息作为页面映射存储为每个内存块(Chunks)的开始处,通过分开存储这些信息,页面只接触它们使用的部分,同时对于超过一半的页,但没有超过一半的内存块的大型分配,这种做法同样高效和安全。

小型分配分为三个类:小、量子尺寸(quantum-spaced)和子页,根据数据类型的不同,现代架构要求内存对齐,malloc(3)要求返回适合边界的内存时,在糟糕的情况下,对齐要求被称为量子尺寸(通常是16字节)。如下图所示:

C指针原理(84)-内存管理与控制_第2张图片

jemalloc分配机制包括领域(arena)、块(chunk)、执行(bin)、运行(run)、线程缓存等部分,jemalloc使用多个分配领域(Arena)将内存分而治之,以块(chunk)作为具体进行内存分配的区域,块(chunk)以页(page)为单位进行管理,每个块(chunk)的前几个 页(page)用于存储后面所有页(page)的状态,后面的所有页(page)则用于进行实际的分配。执行(bin)用来管理各个不同大小单元的分配,每个执行(bin)通过对它对应的运行(run)操作来进行分配的,一个运行(run)实际上就是块(chunk)里的一块区域 ,在分配内存时首先从线程对应的私有缓存空间(tcache)中找。 

     但现代的处理器都是多处理器,并行计算已经慢慢成为一种趋势,多线程运算不可避免,为提高malloc在多线程环境的效率和安全性,增强多线程的伸缩性,Jason Evans 在他的《A Scalable Concurrent malloc(3) Implementation for FreeBSD》一文中提出了并发状态的malloc机制,jemalloc使用多个分配领域(Arena)减少在多处理器系统中的线程之间的锁竞争,虽然增加一些成本,但更有利于提供多线程的伸缩性。现代的多处理器在每个高速缓存线(per-cache-line )的基础上提供了内存的一致性视图,如果两个线程同时运行在不同的处理器上,但在同一缓存线(cache-line)操纵不同的对象,那么处理器必须仲裁缓存线(cache-line)的所有权。


下面是jemalloc的核心层示意:

C指针原理(84)-内存管理与控制_第3张图片

麦好的AI乐园博客所有内容是原创,如果转载请注明来源

http://blog.csdn.net/myhaspl/



你可能感兴趣的:(C语言,内存管理,内存分配)