Tcmalloc源码简单分析(5)

本文深入探讨了span_allocator_初始化函数span_allocator_.Init()的实现细节,包括内存分配与释放策略,以及如何避免碎片化的问题。通过分析New和Delete函数,展示了如何高效地管理内存资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SizeMap初始化完成后,initStaticVars()开始初始化span_allocator_.Init(),并调用两次,主要目的应该是为了能够成功初始化,并保证cache不会存在冲突。;span_allocator_是一个PageHeapAllocatorpage_heap_allocator.h)模板的span实例。span_allocator_.Init()函数比较诡异,开始先将几个数据结构初始化,在最后一行调用了New后立即Delete这部分内容非常有意思。

  void Init() {

    ASSERT(sizeof(T) <= kAllocIncrement);

    inuse_ = 0;

    free_area_ = NULL;

    free_avail_ = 0;

    free_list_ = NULL;

    // Reserve some space at the beginning to avoid fragmentation.

    Delete(New());

  }

我们可以看看NewDelete函数,New函数首先判断free_list是否为NULL,如果非NULL,代表着已经有切出来的object可以用,然后直接从此list里面进行分配(这里面还有个小的技巧,留着后面理解)。如果free_list_NULL,首先判断,是否有足够的已经分配的空间可用,如果有直接从free_area位置切出一块需要的空间,否则得从系统主动malloc128k的空间然后开始分配,并调整free_area_free_avail_inuse_参数,并返回相应的地址。

  T* New() {

    // Consult free list

    void* result;

    if (free_list_ != NULL) {

      result = free_list_;

      free_list_ = *(reinterpret_cast<void**>(result));

    } else {

      if (free_avail_ < sizeof(T)) {

        // Need more room. We assume that MetaDataAlloc returns

        // suitably aligned memory.

        free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement));

// kAllocIncrement = 128 << 10

        if (free_area_ == NULL) {

          CRASH("FATAL ERROR: Out of memory trying to allocate internal "

                "tcmalloc data (%d bytes, object-size %d)\n",

                kAllocIncrement, static_cast<int>(sizeof(T)));

        }

        free_avail_ = kAllocIncrement;

      }

      result = free_area_;

      free_area_ += sizeof(T);

      free_avail_ -= sizeof(T);

    }

    inuse_++;

    return reinterpret_cast<T*>(result);

  }

Delete函数并不真正的free空间,只是将此obj加入已经被切割obj并且空闲的列表,这里面有个非常有意思的东西,就是通过将下一个obj的地址存在当前obj里面,来进行管理,这样可以和上面New函数中红色部分相对应,通过当前位置free_list_中所存放的地址就可以找到下一个空闲地址。。

  void Delete(T* p) {

    *(reinterpret_cast<void**>(p)) = free_list_;

    free_list_ = p;

    inuse_--;

  }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值