Tcmalloc源码简单分析(6)

New中的MetaDataAlloc函数定义在common.cc中,通过调用TCMalloc_SystemAlloc来分配内存,维护一个全局变量metadata_system_bytes用来存储已经分配的内存数。TCMalloc_SystemAlloc首先通过变量system_alloc_inited判断SystemAlloc是否已经初始化,如果没有将调用InitSystemAllocators进行初始化。Allocators是一个包含5Allocator的数组,allocators[2]被定义为DevMemSysAllocatorDevMemSysAlloctor通过mmap /dev/mem的方式来分配内存(后面会详细分析)。而如果开启的是debug模式(kDebugMode)且在64-bits模式下(sizeof(void*) > 4)那么还将初始化allocators[3]MmapSysAllocatorallocators[4]SbrkSysAllocator,让mmapsbr前被调用,而如果以上条件不符合那么sbrk将在mmap前被调用。allocators [0]在函数InitSystemAllocator中被初始化为HugetlbSysAllocator,而allocators[1]没有发现在何处初始化。

void InitSystemAllocators(void) {

  // This determines the order in which system allocators are called

  int i = kMaxDynamicAllocators;

  allocators[i++] = new (devmem_space) DevMemSysAllocator();

                               

  // In 64-bit debug mode, place the mmap allocator first since it

  // allocates pointers that do not fit in 32 bits and therefore gives

  // us better testing of code's 64-bit correctness.  It also leads to

  // less false negatives in heap-checking code.  (Numbers are less

  // likely to look like pointers and therefore the conservative gc in

  // the heap-checker is less likely to misinterpret a number as a

  // pointer).

  if (kDebugMode && sizeof(void*) > 4) {

    allocators[i++] = new (mmap_space) MmapSysAllocator();

    allocators[i++] = new (sbrk_space) SbrkSysAllocator();

  } else {

    allocators[i++] = new (sbrk_space) SbrkSysAllocator();

    allocators[i++] = new (mmap_space) MmapSysAllocator();

  }

}

TCMalloc_SystemAlloc在初始化完毕后,判断alignment是否符合最小对齐,如果不符合那么设置alignment sizeof(MemoryAligner)MemoryAligner是一个union最大应该是64bytes

void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,

                           size_t alignment) {

  // Discard requests that overflow

  if (size + alignment < size) return NULL;

 

  SpinLockHolder lock_holder(&spinlock);

 

  if (!system_alloc_inited) {

    InitSystemAllocators();

    system_alloc_inited = true;

  }

 

  // Enforce minimum alignment

  if (alignment < sizeof(MemoryAligner)) alignment = sizeof(MemoryAligner);

从此处开始,CMalloc_SystemAlloc开始尝试Alloc内存,它会尝试两次,每次都是从allcator[0]开始,到allcator[kMaxAllocators -1]。每个SysAllocator有两个参数分别是usable_ &&failed_,分别用来表示此alloc是否可用以及是否上次分配是已经失败。

  // Try twice, once avoiding allocators that failed before, and once

  // more trying all allocators even if they failed before.

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

    for (int j = 0; j < kMaxAllocators; j++) {

      SysAllocator *a = allocators[j];

      if (a == NULL) continue;

      if (a->usable_ && !a->failed_) {

        void* result = a->Alloc(size, actual_size, alignment);

        if (result != NULL) return result;

      }

    }

 

    // nothing worked - reset failed_ flags and try again

    for (int j = 0; j < kMaxAllocators; j++) {

      SysAllocator *a = allocators[j];

      if (a == NULL) continue;

      a->failed_ = false;

    }

  }

  return NULL;

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值