glibc内存管理ptmalloc - largebin

前言

上节《glibc内存管理ptmalloc》我们讲了fastbin/unsortedbin/smallbin, 有意避开了largebin, 因为largebin稍微复杂一点点,需要单独一节讲解。

largebin的特点

  1. chunk size 大于等于1024字节
  2. largebin共有63个链表
  3. largebin每个链表中的chunk size不固定
  4. largebin中的链表不仅使用fd/bk串起来,还用fd_nextsize、bk_nextsize串起来,目的是跳跃式的寻找下个size大小的chunk. 按size大小排序chunk,大的在前,小的在后。

任意给出一个大于等于1024的size,可根据下面这个宏查在哪个链表中

// XXX It remains to be seen whether it is good to keep the widths of
// XXX the buckets the same or whether it should be scaled by a factor
// XXX of two as well.
#define largebin_index_64(sz)                                                                                                                            \
  (((((unsigned long)(sz)) >> 6) <= 48) ? 48 + (((unsigned long)(sz)) >> 6) : ((((unsigned long)(sz)) >> 9) <= 20) ? 91 + (((unsigned long)(sz)) >> 9)   \
                                                                          : ((((unsigned long)(sz)) >> 12) <= 10)  ? 110 + (((unsigned long)(sz)) >> 12) \
                                                                          : ((((unsigned long)(sz)) >> 15) <= 4)   ? 119 + (((unsigned long)(sz)) >> 15) \
                                                                          : ((((unsigned long)(sz)) >> 18) <= 2)   ? 124 + (((unsigned long)(sz)) >> 18) \
                                                                                                                   : 126)

 我制作了一个表格,更加清晰明了。

例子

目的:设计一个例子,查看largebin链表中的内容,了解fd/bk_nextsize的作用,并验证size与index的映射关系。

int main(int argc, char* argv[])
{
    void* arr[10];
    arr[0] = malloc(20);
    arr[1] = malloc(1024+10);
    arr[2] = malloc(20);
    arr[3] = malloc(1024+10);
    arr[4] = malloc(20);
    arr[5] = malloc(1024+10);
    arr[6] = malloc(20);
    arr[7] = malloc(1024+26);
    arr[8] = malloc(20);
    arr[9] = malloc(1024+26);
    malloc(20);

    for(int i=1;i<10;i+=2) free(arr[i]); //free to unsortedbin
    void* p = malloc(20); //move items in unsortedbin to largebins

    printf("getchar\n");
    getchar();

    return 0;
}

调试到getchar, 1024+10+16(自重)和1024+26+16都属于下标为64-1的链表

(gdb) p main_arena.bins[63*2]
$4 = (mchunkptr) 0x602ce0
(gdb) p main_arena.bins[63*2+1]
$5 = (mchunkptr) 0x602460


(gdb) p *(mchunkptr)0x602ce0  #arr[7]
$6 = {prev_size = 0, size = 1073, fd = 0x603130, bk = 0x7ffff7dd7a88 <main_arena+1096>, fd_nextsize = 0x602020,
  bk_nextsize = 0x602020}
(gdb) p *(mchunkptr)0x603130    #arr[9]
$7 = {prev_size = 0, size = 1073, fd = 0x602020, bk = 0x602ce0, fd_nextsize = 0x0, bk_nextsize = 0x0}
(gdb) p *(mchunkptr)0x602020    #arr[1]
$8 = {prev_size = 0, size = 1057, fd = 0x6028a0, bk = 0x603130, fd_nextsize = 0x602ce0, bk_nextsize = 0x602ce0}
(gdb) p *(mchunkptr)0x6028a0   #arr[5]
$9 = {prev_size = 0, size = 1057, fd = 0x602460, bk = 0x602020, fd_nextsize = 0x0, bk_nextsize = 0x0}
(gdb) p *(mchunkptr)0x602460  #arr[3]
$10 = {prev_size = 0, size = 1057, fd = 0x7ffff7dd7a88 <main_arena+1096>, bk = 0x6028a0, fd_nextsize = 0x0,
  bk_nextsize = 0x0}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深山老宅

鸡蛋不错的话,要不要激励下母鸡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值