• 内存池:

    1.避免频繁分配和释放内存,提高效率

    2.避免内存碎片

    3.避免内存泄露 

    //4.设置对齐,高效存取数据。->这点是在malloc也实现了,并没有提高,而是基本的要求

    char* p=(char*)malloc(8);
    memset(p,0,8);
    *(int*)(p+1)=1;
    printf("addr:0x%x,convert addr:0x%x,data:%d
    ",p,p+3,*(int*)(p+1));
    int i;
    for(i=0; i<8; i++)                                                  
    {
             printf("p[%d]=%x,",i, *(p+i));
    }
    printf("
    ");
    free(p);

    对齐: 为了减少CPU访存次数,CPU 的访问内存有大小和地址上的限制,CPU 只能访问对齐地址上的固定长度的数据,不能跨区间访问。所以,代码里对齐值是多少,CPU并不知道,故如果把一个4字节的变量放在非4的倍数的内存地址上,则需要两次预读取才可完成变量访问,便降低了访问速率。

    对齐地址->字长为w,CPU.....那么在设计上就假设了对宽度为w的数据的处理最频繁也是最重要的,所以优先提高对w位数据操作的效率来考虑的+CPU在存取数据时使用w字长的寄存器,每次存取固定大小的数据(以4Byte为例)->大多处理器被优化而对特定的缓存块进行内存读写,在特定的内存地址上预取数据(在这里是4的倍数)。

    使用缓存->为了提高命中率,同时最少的周期中取出数据。

    固定长度->如果真正需要访问的数据并没有占据那个区间的全部字节范围,就按需进行剔除和合并。

    Intel建议在定义数据时遵守那几条规则,即把n字节的数据定义在n的倍数的内存地址上进行对齐->跨平台,32位机里虽然long按8字节对齐,仍然需要两次访存。但如果不安8倍地址对齐,在64位机就需要两次访存;而按8倍地址对齐,就需一次访存。

    参考:http://bbs.csdn.net/topics/350174356

    http://blog.csdn.net/hairetz/article/details/4084088

     

    对象池--与slab分配机制相通:

    两者的设计思想相通,对于大小小于页大小的对象(数据结构),一次分配一大块连续的内存空间,使用完后并不释放(放回内存的空闲表中),而是保留在池/slab块中,等下次需要相同大小的对象时,先从池/slab块中分配。

    对于应用层对内存空间的申请和释放很方便。但在底层操作系统,在实际分配内存时,都是按照页为单位分配的。这样,多次分配少于一页的空间,各个分配的空间顺序分配存储,若从中释放空间后无法被利用就会产生碎片。而位大小小于一页的固定大小的对象分配一大块空间,使用时从池中取,用完放回池中,被标记为空闲,下次分配时就可填充进入,防止了页内碎片的产生。

    这样做,一方面避免了内存的频繁分配和回收(一个是基于物理内存的分配,一个是逻辑层的)的开销,另一方面,减少了页内碎片的产生

  • 相关阅读:
    [luogu3334]抛硬币
    [luogu3706]硬币游戏
    [luogu4548]歌唱王国
    [hdu4652]Dice
    [atAGC013F]Two Faced Cards
    [atAGC045F]Division into Multiples
    [atAGC045E]Fragile Balls
    [atAGC045D]Lamps and Buttons
    [luogu5574]任务分配问题
    [luogu4331]数字序列
  • 原文地址:https://www.cnblogs.com/wenxuanguan/p/3843463.html
Copyright © 2020-2023  润新知