TCMalloc的使用与源码剖析之四---------内存在各层之间的传递

来源:互联网 发布:centos编译安装php7.1 编辑:程序博客网 时间:2024/05/17 16:16

(1)ThreadCacheCentralCache内存传递

1.ThreadCache内存不够时,要从CentralCache拿(RemoveRange),再把拿到的内存加入ThreadCachelist_[cl]链表队列。(PushRange

2.ThreadCacheCentralCache拿或者返还给CentralCache的内存,是一种什么逻辑?

当拿内存时,如果申请的内存大小是0.23kb,先是找到ThreadCache中对应给0.23kb的内存组的大小是多少,这里假设是0.3kb。然后根据num_objects_to_move(0.3)函数获得每次应该传递的obj的个数。  ThreadCache还内存给CentralCacheReleaseToCentralCache),一次也是还num_objects_to_move(0.3),把该obj全部放到tc_slots,但如果实在是不满足该条件,就把内存还给SpanReleaseListToSpans)。

正常情况肯定是申请num_objects_to_move(cl)obj,除非FreeList本身能容纳的obj个数不够num_objects_to_move(cl)

当要归还的obj个数大于num_objects_to_move(cl),一次还Static::sizemap()->num_objects_to_move(cl)boj,归还给tc_slots_数组。最后多余的不够num_objects_to_move(cl)obj通过ReleaseListToSpans函数归还。

2CentralCache与中央页堆的内存传递

FetchFromSpansSafe()首先会调用FetchFromSpans(从Span中切一个obj对应的内存片),当FetchFromSpans调用失败,也即nonempty队列中对应的span连一个obj的内存都切不出来时,便会调用populate函数从中央页堆中获取内存。倘若FetchFromSpansSafe中的FetchFromSpans能切除一个obj,就不从中央页堆申请内存,RemoveRange函数后续继续用FetchFromSpans切另外N-1obj,倘若此时nonempty中内存只够mobj(m<N-1) ,那么此时就返回mobjThreadCache

中央页堆每次传递给CentralCache的内存也是固定的,每次传递class_to_pages(size_class_)个页面。这n个页面就是一个Span,该span会被切成obj链接起来,然后把该Span插入CentralCachenonempty中。

从中央页堆拿class_to_pages(size_class_)个页面利用的是New函数,该函数首先是在中央页堆的free_或者large_队列中拿内存,如果这两都不符合条件,那么就要从系统内存拿啦(GrowHeap)

 

3)中央页堆与系统内存的内存传递

系统内存每次传递给中央页堆的页面数,与populate函数中传进来的页面数n以及系统参数kMinSystemAlloc有关,如下面的语句:

Length ask =(n>kMinSystemAlloc) ? n : static_cast<Length>(kMinSystemAlloc)  (GrowHeap函数里)

GrowHeap中利用TCMalloc_SystemAlloc向系统申请内存(其底层会调用mmap或者是sbrk)。把系统分配来的内存弄成Span,把生成的Span的信息记录进radix tree, 日后通过页面ID便可通过get函数查找到其对应的Span对象,再通过Delete函数把新生成的Span加入中央页堆的"free_或者large_""norma或者returned队列"(在Delete函数里面,会合并相邻的Span

0 0
原创粉丝点击