部分内容个人感觉不是特别重要,所以没有记录了。其实还是懒

  • embedded pointers

    把对象的前四字节当指针用.

        struct obj{
    struct obj *free_list_link;
    };

    一般工业级的设计里小区块都是大于4字节的,小于四字节的区块不考虑,直接补上。

  • 分配器

    [ C++ ] 勿在浮沙筑高台 —— 内存管理(18~31p) std::alloc-LMLPHP

    分配器 开头的样子。

  • alloc 即_default_alloc_template,二层分配器

    [ C++ ] 勿在浮沙筑高台 —— 内存管理(18~31p) std::alloc-LMLPHP

    ROUND_UP:调到align的边界。

    FREELIST_INDEX:根据size和align取free_list数组下标。

    free_list:指向指针数组元素的指针。

    refill:填充free_list并返回第一个区块的起始地址。(从战备池拿或者malloc分配)

    chunk_alloc: 请求分配一大块内存。

    [ C++ ] 勿在浮沙筑高台 —— 内存管理(18~31p) std::alloc-LMLPHP

    为什么deallocate不释放?因为内存块是否连续难以判断。

    但是同时也会带来内存资源被某个程序一直抓住,没法被其他程序利用。

    deallocate参数的指针必须为8的倍数

    大于MAX_BYTES的allocate和deallocate丢给第一层,即malloc和free。

  • refill:充值

    [ C++ ] 勿在浮沙筑高台 —— 内存管理(18~31p) std::alloc-LMLPHP

    chunk收到 nobjs 块n bytes大小的内存块,其中nobjs可通过引用被修改(如内存不够的情况)。

    result返回第一块地址。

    大致工作流程:

    • 若nobjs==1,则直接返回chunk。
    • 让my_free_list指针指向对应n大小块的数组下标位置。
    • *my_free_list指向 链表第二块位置。(第一块地址做返回值,因为要返回一个对象大小的内存块)
    • 然后就是链表的常规操作。

      (为啥最后一块的判定是nobjs-1?因为第一块跳过了)
  • chunk_alloc:分配一大块内存

    [ C++ ] 勿在浮沙筑高台 —— 内存管理(18~31p) std::alloc-LMLPHP

    [ C++ ] 勿在浮沙筑高台 —— 内存管理(18~31p) std::alloc-LMLPHP

    具体流程如下图:

    [ C++ ] 勿在浮沙筑高台 —— 内存管理(18~31p) std::alloc-LMLPHP

    G2.9 std::alloc先天缺陷:

    1.没法还内存,因为已分配部分的头部没有记录。(设计缺陷)

    2.代码风格不好。

推荐一个更全面的总结:https://cloud.tencent.com/developer/article/1510224

05-24 17:24
查看更多