Tcmalloc源码简单分析(9)

以上过程是span_allocator_.Init()函数的行为,到此已经分析完毕,下面我们继续看Static::InitStaticVars函数,次函数接着将会调用函数stacktrace_allocator_.Init();stacktrace_allocator_的定义如下,PageHeapAllocator<StackTrace> Static::stacktrace_allocator_;这个函数的init也是和span一样,都是为这两个obj预留了相应的空间,并进行了初始化。然后调用bucket_allocator_.Init(),结果也是如上。void Static::InitStaticVars() {

  sizemap_.Init();

  span_allocator_.Init();

  span_allocator_.New(); // Reduce cache conflicts

  span_allocator_.New(); // Reduce cache conflicts

  stacktrace_allocator_.Init();

  bucket_allocator_.Init();

  // Do a bit of sanitizing: make sure central_cache is aligned properly

  CHECK_CONDITION((sizeof(central_cache_[0]) % 64) == 0);

  for (int i = 0; i < kNumClasses; ++i) {

    central_cache_[i].Init(i);

  }

  new ((void*)pageheap_memory_) PageHeap;

  DLL_Init(&sampled_objects_);

  Sampler::InitStatics();

}

 

后面开始初始化central_cachecentral_cache作为整个tcmalloc的核心数据结构,他包含kNumClasses()个CentralFreeListPadded。每个CentralFreeListPadded64bytes对齐,通过一个  char pad_[64 - kFreeListSizeMod64]来实现对齐。

template<int kFreeListSizeMod64>class CentralFreeListPaddedTo : public CentralFreeList {

 private:

  char pad_[64 - kFreeListSizeMod64];

};

template<>class CentralFreeListPaddedTo<0> : public CentralFreeList {

};

 

class CentralFreeListPadded : public CentralFreeListPaddedTo<  sizeof(CentralFreeList) % 64> {

};

central_cache_的每个class都会通过调用下面的init函数进行初始化,init函数的调用参数为当前classnum,通过classnum初始化CentralFreeListsize_class_(本classclass num,通过class_to_size_可获得本class可以分配的最大objsize)。DLL_Init只是简单的将spannextprev指针指向自己。然后初始化counter_=0(Number of free objects in cache entry)cache_size_used_slots_的初始化和数据结构TCEntry tc_slots_[kNumTransferEntries]有关,TCEntry主要用来cache thread caches and the central cache之间的transfers of sizemap.num_objects_to_move(size_class) used_slots_代表现在正在使用中的tc_slots_数量,而cache_size_代表当前可使用的slots,当然这个数字可根据流量动态调整。

void CentralFreeList::Init(size_t cl) {

  size_class_ = cl;

  tcmalloc::DLL_Init(&empty_);

  tcmalloc::DLL_Init(&nonempty_);

  counter_ = 0;

 

  cache_size_ = 1;

  used_slots_ = 0;

  ASSERT(cache_size_ <= kNumTransferEntries);

}

初始化完毕central_cache_后调用PageHeap的构造函数对char Static::pageheap_memory_[sizeof(PageHeap)]进行初始化。PageHeap的初始化函数如下所示,首先初始化pagemap_page_map是一个三层的radix tree,他的初始化函数通过设置allocatorMetaDataAlloc,并利用MetaDataAlloc new出一个node作为rootpagemap_cache_是一个PackedCache<BITS-kPageShift, uint64_t>。他主要用作minimal cache that can hold a <key, value>。每个cache entry都用一对<key, value>来表示。free_ list主要用来存储本PageHeap中的各个sizespan

 

PageHeap::PageHeap()

    : pagemap_(MetaDataAlloc),

      pagemap_cache_(0),

      scavenge_counter_(0),

      // Start scavenging at kMaxPages list

      release_index_(kMaxPages) {

  COMPILE_ASSERT(kNumClasses <= (1 << PageMapCache::kValuebits), valuebits);

  DLL_Init(&large_.normal);

  DLL_Init(&large_.returned);

  for (int i = 0; i < kMaxPages; i++) {

    DLL_Init(&free_[i].normal);

    DLL_Init(&free_[i].returned);

  }

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值