Chinaunix首页 | 论坛 | 博客
  • 博客访问: 68152
  • 博文数量: 19
  • 博客积分: 425
  • 博客等级: 下士
  • 技术积分: 239
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-08 15:35
文章分类

全部博文(19)

文章存档

2012年(2)

2011年(17)

我的朋友

分类: LINUX

2011-10-08 15:54:16

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;

}

阅读(1050) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~