malloc alloc_new_heap

ptmalloc2 中为非主 Arena 分配新堆段的核心函数。它通过 mmap 向操作系统申请一块内存,并在其上初始化 heap_info 结构体,然后将其挂接到 Arena 的堆段链表中。

函数签名

static heap_info *
alloc_new_heap  (size_t size, size_t top_pad, size_t pagesize,
                 int mmap_flags)

参数说明

参数含义
size请求的堆段大小(用于分配 chunk 的空间)
top_padTop Chunk 填充量(默认 128KB)
pagesize系统页大小(通常 4KB)
mmap_flagsmmap 的标志位(如 MAP_PRIVATE | MAP_ANONYMOUS

核心逻辑拆解

1. 计算实际需要映射的大小
size = ALIGN_UP (size + top_pad + sizeof (heap_info), pagesize);
  • size:请求的 chunk 空间。

  • top_pad:额外的填充量,减少后续扩展频率。

  • sizeof(heap_info)heap_info 结构体本身占用的空间。

  • ALIGN_UP(..., pagesize):向上对齐到页边界,因为 mmap 要求页对齐。

2. 尝试不同的 mmap 标志组合
if (mmap_flags & MAP_HUGETLB)
  {
    // 尝试使用大页
    mm = (char *) MMAP (0, size, PROT_READ | PROT_WRITE,
                        MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
    if (mm != MAP_FAILED)
      goto success;
  }

// 回退到普通页
mm = (char *) MMAP (0, size, PROT_READ | PROT_WRITE,
                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mm == MAP_FAILED)
  return 0;
  • 如果请求了 MAP_HUGETLB,先尝试用大页映射。

  • 如果大页失败,回退到普通页。

  • 如果普通页也失败,返回 0(分配失败)。

3. 初始化 heap_info
success:
  h = (heap_info *) mm;
  h->size = size;
  h->mprotect_size = size;
  h->ar_ptr = NULL;  // 稍后由调用者设置
  h->prev = NULL;    // 稍后由调用者设置
  return h;
  • h->size:记录堆段的总大小。

  • h->mprotect_size:记录已设置内存保护的大小。

  • h->ar_ptr 和 h->prev:由调用者(new_heap 或 grow_heap)后续设置。

调用者:new_heap

alloc_new_heap 通常被 new_heap 调用,后者负责将新堆段挂接到 Arena:

static heap_info *
new_heap (size_t size, size_t top_pad)
{
  heap_info *h = alloc_new_heap (size, top_pad, GLRO (dl_pagesize), 0);
  if (h == NULL)
    return NULL;
  
  // 设置 heap_info 的 ar_ptr 和 prev
  h->ar_ptr = ...;
  h->prev = ...;
  
  return h;
}

与 grow_heap 的区别

函数作用是否创建新堆段
alloc_new_heap通过 mmap 分配全新的堆段✅ 是
grow_heap通过 mprotect 扩展现有堆段的可写区域❌ 否
new_heap调用 alloc_new_heap,并初始化堆段信息✅ 是

注意事项

  1. mmap 失败处理:如果 mmap 返回 MAP_FAILED,函数返回 0,调用者需要处理。

  2. 大页回退:如果请求了大页但失败,会回退到普通页。这是为了兼容不支持大页的系统。

  3. ar_ptr 和 prev 未初始化alloc_new_heap 只负责分配和初始化 size 和 mprotect_sizear_ptr 和 prev 由调用者设置。

  4. 页对齐size 必须向上对齐到 pagesize,否则 mmap 会失败。

  5. top_pad 的作用:额外的填充量,减少后续 grow_heap 的频率。默认 128KB。

总结

要点说明
功能通过 mmap 为非主 Arena 分配新堆段
大小计算size + top_pad + sizeof(heap_info),向上对齐到页
大页支持如果请求 MAP_HUGETLB,先尝试大页,失败回退普通页
初始化设置 heap_info 的 size 和 mprotect_size
调用者new_heap 负责设置 ar_ptr 和 prev
与 grow_heap 区别alloc_new_heap 创建新堆段,grow_heap 扩展现有堆段

一句话理解

alloc_new_heap 是 ptmalloc2 为非主 Arena “开疆拓土”的函数。它通过 mmap 向操作系统申请一块新的、页对齐的内存,在上面初始化 heap_info 结构体,然后返回给调用者。调用者再将它挂接到 Arena 的堆段链表中,成为该 Arena 新的可用内存来源。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值