您的位置:首页 > 其它

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

2016-10-22 10:41 239 查看

(1)ThreadCache与CentralCache内存传递

1.ThreadCache内存不够时,要从CentralCache拿(RemoveRange),再把拿到的内存加入ThreadCache的list_[cl]链表队列。(PushRange)
2.ThreadCache从CentralCache拿或者返还给CentralCache的内存,是一种什么逻辑?
当拿内存时,如果申请的内存大小是0.23kb,先是找到ThreadCache中对应给0.23kb的内存组的大小是多少,这里假设是0.3kb。然后根据num_objects_to_move(0.3)函数获得每次应该传递的obj的个数。
ThreadCache还内存给CentralCache(ReleaseToCentralCache),一次也是还num_objects_to_move(0.3)个,把该obj全部放到tc_slots,但如果实在是不满足该条件,就把内存还给Span(ReleaseListToSpans)。
正常情况肯定是申请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函数归还。

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

FetchFromSpansSafe()首先会调用FetchFromSpans(从Span中切一个obj对应的内存片),当FetchFromSpans调用失败,也即nonempty队列中对应的span连一个obj的内存都切不出来时,便会调用populate函数从中央页堆中获取内存。倘若FetchFromSpansSafe中的FetchFromSpans能切除一个obj,就不从中央页堆申请内存,RemoveRange函数后续继续用FetchFromSpans切另外N-1个obj,倘若此时nonempty中内存只够m个obj的(m<N-1)
,那么此时就返回m个obj给ThreadCache。
中央页堆每次传递给CentralCache的内存也是固定的,每次传递class_to_pages(size_class_)个页面。这n个页面就是一个Span,该span会被切成obj链接起来,然后把该Span插入CentralCache的nonempty中。
从中央页堆拿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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐