TCMalloc的使用与源码剖析之三---------TCMalloc的内存分配的主要层次
2016-10-22 10:32
211 查看
(1)第一层,线程局部分配,ThreadCache
ThreadCache包含了一个不同对象大小的空闲链表数组,其实现采用操作系统的线程局部存储功能。分配时几乎不需要用锁,除非触发CentralCache的操作。ThreadCache中的重要数据结构:
pthread_t tid_; 绑定线程,达到每个线程有个缓冲池的目的
FreeList list_[kNumClasses];
这个数组就是上图中的第一列,如下图
数组中的每一个节点就是代表上图中的每一行,如下图
每个class对应多大的内存空间?这个表示每组的大小的变量在哪里?
不存在这样的变量,但是通过映射关系可以达到一个class管一类size的作用,
如下图所示,由cl
得到list_[cl],这也即是一个class。
至于cl,是由class_array_得到的,关于这个内容在第五章:几个重要的数据结构
若申请的内存是13字节,但分配的却是15字节,那么便会有2个字节的内存碎片(内部碎片)。
(2)第二层 ,中心分配,Centralcache
该层的分配需要锁。CentralCache和ThreadCache之间的空闲链表是一一对应的,以子链表为单位(obj个数很可能为num_objects_to_move(cl),见do_malloc与do_free流程图)进行互相交换。CentralCache的内存从PageHeap里获得。从PageHeap获得的内存叫Span。一个Span在使用时只能用于同一大小的空闲链表,一但CentralCache从PageHeap中获取新的Span,这个Span就是一个串好的相同大小内存的空闲链表。
Centralcache中有几个重要数据结构:
1. TCEntry tc_slots_[kMaxNumTransferEntries];
tc_slots_每个节点存放的是一组obj链表,这一组obj的个数为num_objects_to_move,TCEntry结构体有两指针,分别指向这个链表的头和尾。
tc_slots_存放的是threadCache向CentralCache归还的obj链表,并且只有当个数满足num_objects_to_move时,才会放入tc_slots_。否则归还的obj根据其所处的span,进行归还,若对应的span是empty,那么由于此时被归还内存了,所以其有空闲obj了,便把该span从empty队列清除,把其加入nonempty队列。
2. span empty
FetchFromSpans函数把一个obj从nonempty队列中的一个span中切出,准备给threadCache。当切完这个obj后,如果该span已经没有内存空间了,那么便把该span从nonempty队列移除,并加入empty队列。
3. span nonempty
CentralCache从中央页堆申请页面,中央页堆以span的形式返回。在CentralCache中会把该span切成大小为class_to_size的obj,并把所有的obj链接起来,链表头为span->objects。再把该链表加入nonempty队列。
Nonempty队列另外一个被加入span的地方在内存从threadCache归还给CentralCache时,具体情况见上面”tc_slots_”这一数据结构的描述。
(3)第三层,中央页堆,PageHeap
PageHeap以一定数量连续页面内存的形式提供内存。这组连续的页面由一个Span对象描述,Span对象和它描述的页面内存是独立的。Span对象保存了页面的id序列,页面id左移一个page就是内存的地址。由于页面和Span内存独立,需要用pageid反向映射查找Span对象就需要单独的映射表。这个表用radix tree实现,兼顾效率和内存。PageHeap还负责合并和拆分相邻的Span。
PageHeap重要数据结构:
SpanList large_;
SpanList free_[kMaxPages];
中央页堆是由空闲内存列表组成的数组。对于i< 256而言,数组的第k个元素是一个由每个单元是由k个页面组成的空闲内存链表(这也即是free_)。第256个条目(这即是large_)则是一个包含了长度>=
256个页面的空闲内存链表:
而SpanList为
struct SpanList {
Span normal;
Span returned;
};
Returned代表的是已经归还给系统的span
(4)第四层,系统页面分配,
这就是调用系统函数了。相关文章推荐
- TCMalloc的使用与源码剖析之六---------TCMalloc中内存分配流程
- TCMalloc的使用与源码剖析之八---------TCMalloc内存分配与释放的管理之内存泄露检查
- TCMalloc的使用与源码剖析之二---------TCMalloc内存分配与管理简述
- TCMalloc的使用与源码剖析之四---------内存在各层之间的传递
- 内存管理(三)tcmalloc1 内存分配及源码剖析
- Redis使用TCMalloc提高内存分配性能
- TCMalloc的使用与源码剖析之一---------TCMalloc 安装和使用
- 关于redis源码的内存分配,jemalloc,tcmalloc,libc
- Android SDK提供了2个主要的剖析应用程序内存使用情况的工具
- TCMalloc的使用与源码剖析之五---------TCMalloc中涉及到的几个重要的数据结构
- TCMalloc的使用与源码剖析之十--------TCMalloc与APR,ptmalloc的分析比较
- TCMalloc的使用与源码剖析之九---------一些未解决的问题
- TCMalloc的使用与源码剖析之七---------TCMalloc中内存释放流程
- 使用TCMalloc可选择使用内存分配程序
- 20130331 stl源码剖析之stl分配内存设计
- 使用CRT调试内存分配堆来找出未释放的内存空间
- Linux进程间通信源码剖析,共享内存(shmget()、shmat()、shmdt()及shmctl())
- [Linux内核完全剖析]第五章Linux内核体系结构5.1-5.3总结 Linux内存空间分配
- C++中vectors内存分配的使用方法
- Linux进程间通信源码剖析,共享内存(shmget函数详解)