ptmalloc——fastbins

用户free掉的内存并不是都马上归还给系统。相反,ptmalloc会统一管理heap中的空闲chunk,当用户进行下一次分配请求时,ptmalloc会首先试图在heap中空闲的chunk中挑选合适的chunk给用户,这样就避免了频繁的系统调用,降低了内存分配的开销。ptmalloc将heap中相似大小的chunk用链表连接起来,这样的一个链表被称为bin。

通常情况下,程序在运行过程中可能会经常分配和释放一些较小的内存空间,而ptmalloc会对相邻的小的chunk进行合并,当合并之后,可能又会有一个小块内存的请求,ptmalloc又需要从大块的chunk中分出一个chunk出来,这样无疑是比较低效的。因此ptmalloc在分配过程中引入了fastbins。不大于MAX_FAST_SIZE(对于64位系统为160字节)的chunk被free后,首先会被存放到fastbins中;当给用户分配的chunk小于或等于MAX_FAST_SIZE时,优先从fastbins中查找相应的空闲块。

ptmalloc初始时,将fastbins的最大值设置为128字节,即chunk的长度小于或等于128字节时,free掉后被存放到fastbin中,同样,需要分配的chunk长度小于等于128字节时,优先从fastbins中进行查找。另外,fastbins中相同大小的chunk构成一个单链表,以FIFO的形式回收和分配。两个相邻的fastbins中的chunk大小相差16字节。

fastbins中的chunk在内存中大概如下图所示:

一段验证fastbins回收和分配的代码

#define    DEF_ARRAY_NUM    10
#define    DEF_MALLOC_SIZE  17

void test_fastbin()
{
    char * p[DEF_ARRAY_NUM];

    int i = 0;
    int size = DEF_MALLOC_SIZE;

    for( i = 0; i < DEF_ARRAY_NUM; i++ ) {
        p[i] = (char*)malloc(size);
        char * pChunk = p[i] - 16;
        printf("[%d]: mem %p chunk %p\n", i, p[i], pChunk);
    }
    // 释放部分内存
    for( i = 0; i < 3; i++ ) {
        if( NULL != p[i] ){
            free(p[i]);
        }
    }
    // 查看释放掉的内存 chunk的链接情况
    for( i = 2; i >= 0; i-- ) {
        if( NULL != p[i] ) {
            size_t val = *((size_t *)p[i]);
            printf("[%d] mem %p next chunk-> %p\n", i, p[i], val);
        }
    }

    // 再申请一块新的内存
    char * tmp = NULL;
    tmp = (char*)malloc(size);
    printf("tmp mem: %p\n", tmp);

    for( i = 3; i < DEF_ARRAY_NUM; i++ ) {
        if( NULL != p[i] ) {
            free(p[i]);
        }
    }

    free(tmp);
    tmp = NULL;
}

调用该函数的运行结果为:

[0]: mem 0x1098010 chunk 0x1098000
[1]: mem 0x1098030 chunk 0x1098020
[2]: mem 0x1098050 chunk 0x1098040
[3]: mem 0x1098070 chunk 0x1098060
[4]: mem 0x1098090 chunk 0x1098080
[5]: mem 0x10980b0 chunk 0x10980a0
[6]: mem 0x10980d0 chunk 0x10980c0
[7]: mem 0x10980f0 chunk 0x10980e0
[8]: mem 0x1098110 chunk 0x1098100
[9]: mem 0x1098130 chunk 0x1098120

[2] mem 0x1098050 next chunk-> 0x1098020
[1] mem 0x1098030 next chunk-> 0x1098000
[0] mem 0x1098010 next chunk-> (nil)

tmp mem: 0x1098050

 

转载于:https://my.oschina.net/hncscwc/blog/994671

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值