内存池的意义与原理

内存池的原理

一 内存池的用处

为什么需要内存池

如果用户每次需要动态内存时,就调用malloc/calloc取申请内存,不用时就使用free释放内存,会带来两个问题:
1.影响系统效率。函数malloc/calloc对系统的消耗比较大,会占用较多的时间,影响系统的效率。
2.会造成内存碎片化的问题。频繁的申请释放内存,会导致内存中有大量没有连成片的小块内存。
因此,为了解决这两个问题,内存池的概念就诞生了。

内存池的作用及原理是什么

内存池最重要的目的是为了消灭碎片化,内存池是一个由已经分配好的内存快组成的一个池子,当用户需要动态内存时,会从内存池中获得一块合适的内存,当用户不需要这块内存时,会由内存池回收,重新添加到内存池中。内存碎片化的问题则由内存池来解决。

二 内存池的实现

使用场景:
1.全局内存池
2.一个链接做一个内存池
如果使用全局内存池,最好用tcmalloc等开源库,因为自己手写的容易出错。如果是一个链接做一个内存池,在用自己手写的。

本次我实现的内存池是固定内存块的内存池。此内存池将内存分为大块和小块。用户申请和释放小块的内存,则由内存池处理。申请时从内存池中获取需要的内存块,释放时将内存块返回给内存池。如果用户申请和释放的是大块内存,则直接申请和释放内存,这些内存不由内存池管理。

内存池的数据结构如下:

struct mp_large_s {
    struct mp_large_s *next;
    void *alloc;
};

struct mp_node_s { //节点
    unsigned char *last;
    unsigned char *end;

    struct mp_node_s *next;
    
};

struct mp_pool_s {  //内存池的属性
    struct mp_node_s *small;
    struct mp_large_s *large;

    int size;
};

初始化内存池时,内存池会申请一个mp_pool_s结构体大小加2K的内存空间,当用户申请小块空间时,内存池会从2K内存中按照顺序划分合适的内存给它。如果这2K内存不够,会额外再申请2K内存,并将新申请的内存块放到链表首部,然后重新申请的这块内存中顺序分配内存。
如果用户申请的是大块内存,内存池会现在2K内存中申请一个mp_large_s结构体,然后再向系统直接申请内存,并把地址赋值给mp_large_s.alloc。

申请小块内存时一定要内存对齐。
内存对齐指的是元素按照定义顺序依次放到内存中去,但不是紧密排列的,从结构体的首位置,每个元素都以为内存是按照自己的大小划分的,所以元素一定会放到自己大小的整数倍的地址上开始。
内存对齐的原因:
1.方便平台移植。有些硬件平台不能访问全部的内存地址,只能访问特定的,内存不对齐的地址访问不了
2.提高性能。内存对齐后访问元素的速度更快。

三 内存池的工作流程

内存池的工作流程如下:
1.创建内存池;
2.分配内存;
3.判断是否是大块内存,如果是,跳转到第4步,如果不是,跳转到第6步;
4.分配大块内存;
5.返回大块内存首地址。
6.便利现有的内存池,寻找合适的空间分配内存;
7.判断现有内存池是否有可分配的内存池,如果有,转到第8步,否则第9步;
8.返回在现有内存池已分配空间首地址。
9.分配新的内存池;
10.返回在新的内存池已分配空间首地址。

你可能感兴趣的:(C++服务器开发,c语言,开发语言)