欢迎光临
我们一直在努力

malloc 代码之 unsorted_chunks

这个宏定义了 Unsorted Bin 的入口。它用 bin_at(M, 1) 获取第 1 号 bin 的哨兵节点地址,而这个 bin 就是专门用来存放“未排序”空闲 chunk 的容器。


源码定义

/* The otherwise unindexable 1-bin is used to hold unsorted chunks. */
#define unsorted_chunks(M) (bin_at (M, 1))


逐步拆解

1. bin_at(M, 1)

回顾 bin_at 的定义:

#define bin_at(m, i) \\
(mbinptr)(((char *)&((m)->bins[((i) – 1) * 2])) – \\
offsetof(struct malloc_chunk, fd))

当 i = 1 时:

(i – 1) * 2 = 0
bin_at(M, 1) = (char *)&M->bins[0] – offsetof(malloc_chunk, fd)

也就是说,bin_at(M, 1) 返回的是 bins[0] 和 bins[1] 组成的“虚拟 chunk”的起始地址。

2. 为什么是“otherwise unindexable”?

注释说“otherwise unindexable”(原本无法被索引的),是因为:

  • bins 数组的索引 0 在逻辑上被保留,不对应任何常规大小的 bin。

  • 常规的 Small Bin 从 i = 2 开始,Large Bin 从 i = 64 开始。

  • 如果不用 i = 1 来存放 Unsorted Bin,那么 bins[0] 和 bins[1] 这两个数组元素就会被浪费。

所以 ptmalloc2 巧妙地把 i = 1 这个“空位”分配给了 Unsorted Bin,让它有一个合法的“家”。


Unsorted Bin 的用途

Unsorted Bin 是 ptmalloc2 中的中转站,主要承担以下职责:

场景行为
释放 chunk 不直接放入 Small/Large Bin,而是先放入 Unsorted Bin
分配 chunk 优先遍历 Unsorted Bin,寻找合适的块
整理 遍历时,将不符合需求的块“分拣”到对应的 Small/Large Bin

关键特性:

  • 只有一个 Unsorted Bin,大小不分类。

  • 所有放入其中的 chunk 大小无序。

  • 采用 LIFO(后进先出) 策略,最近释放的块最先被检查。


与其他宏的关系

宏对应 bin用途
unsorted_chunks(M) bin_at(M, 1) Unsorted Bin
bin_at(M, i) i = 2~63 Small Bin
bin_at(M, i) i = 64~126 Large Bin
bin_at(M, 127) 保留未使用

访问方式:

// 获取 Unsorted Bin 的哨兵
mbinptr unsorted = unsorted_chunks(av);

// 遍历 Unsorted Bin
for (victim = unsorted->fd; victim != unsorted; victim = victim->fd) {
// 处理每个 chunk
}


在内存布局中的位置

bins 数组:
┌─────────────────────────────────────────────┐
│ bins[0] │ bins[1] │ bins[2] │ bins[3] │ … │
│ fd │ bk │ fd │ bk │ │
└─────────────────────────────────────────────┘


unsorted_chunks(M) = bin_at(M, 1)
指向 bins[0] – offsetof(fd) 的位置
即虚拟 chunk 的起始地址

逻辑 bin 索引:
┌─────────────────────────────────────────────┐
│ i=1 │ i=2 │ i=3 │ … │ i=127 │
│Unsorted │Small 1 │Small 2 │ │ 保留 │
└─────────────────────────────────────────────┘


注意事项

  • i 从 1 开始,不是 0:这是 bin_at 的设计约定。i = 1 对应 bins[0] 和 bins[1]。

  • Unsorted Bin 只有一个:不像 Small/Large Bin 有多个,Unsorted Bin 是唯一的。

  • 遍历终止条件:victim != unsorted,因为它是循环双向链表。

  • unsorted_chunks 是宏,不是函数:它在编译时展开,没有运行时开销。


  • 总结

    要点说明
    功能 获取 Unsorted Bin 的哨兵节点地址
    定义 bin_at(M, 1)
    位置 bins[0] 和 bins[1]
    为什么是 1 索引 0 在逻辑上被保留,用 1 来存放 Unsorted Bin
    用途 作为释放和分配之间的中转站,延迟排序
    遍历 从 unsorted->fd 开始,直到回到 unsorted

    一句话理解:

    unsorted_chunks(M) 就是 Unsorted Bin 的“门牌号”。它利用 bins 数组中原本无法被索引的第 1 号位置,为未排序的空闲 chunk 提供了一个临时的家。所有释放的块先来这里“报到”,等待被分拣到正确的 Small 或 Large Bin 中。

    赞(0)
    未经允许不得转载:171主机测评 » malloc 代码之 unsorted_chunks
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址