Tcmalloc源码简单分析(2)

Free过程

1、             首先free根据提供的ptr指针,获得此ptr所在的页面,然后利用页面号,获取需要释放的objsize,这个size首先从pagemap_cache_中拿,如果不在pagemap_cache_中那么直接通过页面好获取所在的span,如果spanNULL,那么直接报错返回,否则通过span获取需要释放的objsize,并将sizepage的关系放入pagemap_cache_

2、             如果能够获取ptr所指objsize,且本释放是在子线程内(可以获取threadcache),那么调用threadcacheDeallocate释放,转到一下步。否则利用InsertRange直接将obj插入Centralcache对应sizefreelist。如果ptr所指的obj size0,有可能是大的obj,直接从pageheap中拿的,那么跳第5步。

3、             Threadcache通过相应的size获得对应的freelist,然后通过pushobj链入freelist。如果插入之后的list太长将通过ReleaseToCentralCachenum_objects_to_moveobj返还给CentralCache,如果整个threadcachesize太大,那么将对整个free数组进行遍历,调用ReleaseToCentralCache函数。

4、             ReleaseToCentralCache将通过对应CentralCachefreelist调用InsertRange将需要返还给CentralCacheobjs插入CentralCacheCentralCache判断所返还的obj数量是不是正好等于num_objects_to_move,如果是且slots_里面有空闲区,那么直接返还给slots_,否则将这些obj返回给相应的Span,如果本Span通过返还之后已经是有freeobj了,将此Spanempty_列表转移到nonempty_列表,如果此Span已经全部空闲了,没有还在被使用的obj,那么通过Static::pageheap()->Delete返还给pageheap

5、             Pageheap通过Delete函数将返还回来Span的相关参数清零,并设置当前SpanON_NORMAL_FREELIST。然后判断此Span能不能和前后相邻的Span合并,然后将Span插入相应sizenormal队列,最后判断是否需要回收,如果需要,尝试回收至少一个页面,回收动作主要讲Spannormal列表转移到return列表,并调用TCMalloc_SystemRelease将页面标记为可回收的,然后通过系统调用madvise(reinterpret_cast<char*>(new_start), new_end - new_start,                   MADV_DONTNEED)将物理内存返回给系统,而保留虚拟内存。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值