Chinaunix首页 | 论坛 | 博客
  • 博客访问: 65953
  • 博文数量: 19
  • 博客积分: 425
  • 博客等级: 下士
  • 技术积分: 239
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-08 15:35
文章分类

全部博文(19)

文章存档

2012年(2)

2011年(17)

我的朋友

分类: LINUX

2011-10-08 15:36:15

这段时间由于工作中涉及到内存疯长的事情,工作之余就对比分析了tcmalloc和ptmalloc的一些工作方式,关于ptmalloc代码的分析,已经有前人做了不少的工作,我这边主要讲述一下,我对tcmalloc的一点理解,写的比较随意,难免漏洞百出,有问题希望大家能够指正(email:huangjiangwei@gmail.om)开始写写还行,写到后面就不想写了,所以后面的章节代码多于评论和分析,自己都不想看下去了。
 
 

Tcmalloc通过preload或者直接动态链接的方式对malloc等内存分配和释放函数进行截获并提供服务。Tcmalloc提供接口主要涵盖malloc.h的接口。下面我将通过内存操作的基本流程,从分配开始到释放简单的分析tcmalloc的一些内部实现。

首先我们来看内存的分配。在tcmalloc中,内存分配malloc的入口为tc_mallocnew的入口为tc_new,相应的realloccallocmemalignvalloc等也有相应的入口。先简单描述一下tcmalloc的malloc过程和free过程。
 

Malloc过程

1、               Tcmalloc首先判断mallocsize是否大于kMaxSize8u * kPageSize32k),如果小于这个值,那么将size转换为想的obj class,然后从当前thread私有的cacheAllocate,转至第2步。如果请求的size大于kMaxSize那么跳至第10

2、               首先判断当前的threadcacheobj calss对应的freelist中是否包含有空闲的obj,如果有直接pop出来,否则从CentralCache中拿,转下一步。

3、               CentralCacheThreadCache之间obj的转移采用batch方式,每次转移固定数量的obj,这个数量通过Static::sizemap()->num_objects_to_move定义,当然在决定最终转移数量时还是需要不能超过ThreadCache相应listmaxlength。然后通过CentralCache对应freelistRemoveRange函数将确定大小的obj转移出来,并通过对应listPushRange函数将这些obj插入ThreadCache对应的freelist

4、               CentralCache通过RemoveRange将特定数量的obj移出,CentralCache将连续的内存看做一个SpanSpanCentralCache管理内存的一个主要数据结构。而Span又被切分成N个统一大小的obj。每个CentralCache管理属于某个特定classobj。在同一个CentralCache中所包含的obj大小符合特定calss的要求。CentralCache包含kNumTransferEntrieskNumClasses)个slots,这些slots用来存储正好包含num_objects_to_moveobjSpan。如果slots满了或者包含其他数量objSpan将统一放入两个Span队列,emptynonempty。这里的名字比较诡异empty函数存放的Span不是空闲的Span而是Span里面没有空闲objSpannonempty则相反。

5、               因此在Allocate的过程中,首先判断需要Allocateobj数量是不是正好符合num_objects_to_move,如果是而且CentralCache用来存放spanslots不为空,那么直接从slots里面拿,否则从nonempty队列中的Span拿。

6、               Nonempty队列存放了所有可用的Span,那么从头开始一个个拿,如果拿光了还是不能满足要求,那么只能通过向pageheap要求一个span,这个spansizeclass_to_pages决定,然后再将这个Span切成obj返回给CentralCache。然后再次尝试从Span分配。

7、               Pageheap管理整个系统page级别的allocate,他通过两个数据结构管理所有的Spanfree_数组和large_列表),free_数组存放size小于kMaxPages1 << (20 - kPageShift)256)的Span,而large_列表存放大于等于kMaxPagesSpanPageHeap首先判断要求的pages是否大于等于kMaxPages,如果小于那么先从free数组中找,从要求大小的位置开始往后找,先找normal队列在找return对队列。如果在normal队列中找到且找到的Span状态为Span::ON_NORMAL_FREELIST,那么直接从里面切出需要的Span返回给CentralCache。如果在return队列中找到且找到的Span状态为Span:: ON_RETURNED_FREELIST那么直接从里面切出需要的Span返回给CentralCache

8、               如果需要的size不符合上述要求或者在上述队列中没有找到那么将从large_队列中找。从large_队列中查找时,首先从normal队列入手,然后再从return队列找,他将找到size最符合且地址在空闲Span中最小的Span,然后切出来返回。

9、               如果large_队列中都没有找到合适的Span,那么将通过GrowHeap增长Heap的方式,通过TCMalloc_SystemAlloc向系统申请不小于1M的内存。并包装成Span,并插入heap中,然后再次进行分配。

10、           来到此处代表分配的内存是大于32k的,那么将向heap直接请求跳到第7步。

阅读(1890) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:Tcmalloc源码简单分析(2)

给主人留下些什么吧!~~