zoukankan      html  css  js  c++  java
  • 57、什么是内存池,如何实现

    内存池(Memory Pool) 是一种内存分配方式。通常我们习惯直接使用new、malloc 等申请内存,这 样做的缺点在于:由于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性 能。内存池则是在真正使用内存之前,先申请分配一定数量的、大小相等(一般情况下)的内存块留作备 用。当有新的内存需求时,就从内存池中分出一部分内存块, 若内存块不够再继续申请新的内存。这样 做的一个显著优点是尽量避免了内存碎片,使得内存分配效率得到提升。

    这里简单描述一下《STL源码剖析》中的内存池实现机制:

    allocate包装malloc,deallocate包装free

    一般是一次20*2个的申请,先用一半,留着一半,为什么也没个说法,侯捷在STL那边书里说好像是 C++委员会成员认为20是个比较好的数字,既不大也不小

    1. 首先客户端会调用malloc()配置一定数量的区块(固定大小的内存块,通常为8的倍数),假设40 个32bytes的区块,其中20个区块(一半)给程序实际使用,1个区块交出,另外19个处于维护状 态。剩余20个(一半)留给内存池,此时一共有(20*32byte)

    2. 客户端之后有有内存需求,想申请(20*64bytes)的空间,这时内存池只有(20*32bytes),就 先将(10*64bytes)个区块返回,1个区块交出,另外9个处于维护状态,此时内存池空空如也

    3. 接下来如果客户端还有内存需求,就必须再调用malloc()配置空间,此时新申请的区块数量会增加 一个随着配置次数越来越大的附加量,同样一半提供程序使用,另一半留给内存池。申请内存的时 候用永远是先看内存池有无剩余,有的话就用上,然后挂在0-15号某一条链表上,要不然就重新 申请。

    4. 如果整个堆的空间都不够了,就会在原先已经分配区块中寻找能满足当前需求的区块数量,能满足 就返回,不能满足就向客户端报bad_alloc异常

    allocator就是用来分配内存的,最重要的两个函数是allocate和deallocate,就是用来申请内存和回收 内存的,外部(一般指容器)调用的时候只需要知道这些就够了。内部实现,目前的所有编译器都是直 接调用的::operator new()和::operator delete(),说白了就是和直接使用new运算符的效果是一样的, 所以老师说它们都没做任何特殊处理。

    最开始GC2.9之前:

    new和 operator new 的区别:new 是个运算符,编辑器会调用 operator new(0)

    operator new()里面有调用malloc的操作,那同样的 operator delete()里面有调用的free的操作

    GC2.9的alloc的一个比较好的分配器的实现规则

    维护一条0-15号的一共16条链表,其中0表示8 bytes ,1表示 16 bytes,2表示 24bytes。。。。而15 表 示 16* 8 = 128bytes,如果在申请时并不是8的倍数,那就找刚好能满足内存大小的那个位置。比如想 申请 12,那就是找16了,想申请 20 ,那就找 24 了

    但是现在GC4.9及其之后 也还有,变成_pool_alloc这个名字了,不再是默认的了,你需要自己去指定它 可以自己指定,比如说vector<string,__gnu_cxx::pool_alloc> vec;这样来使用它,现在用的又回到以前 那种对malloc和free的包装形式了

  • 相关阅读:
    通过IMM With Remote Console为服务器安装操作系统
    linux下编译安装php5.6出现 configure: error: Cannot find MySQL header files under /usr/local/mysql.
    5700交换机清除配置
    嵌入式驱动解析:从串口驱动到Linux驱动模型
    Win10自带Ubuntu子系统的安装与配置
    关于嵌入式C代码优化的几种方法
    2020软考高级系统分析师,你想知道的全在这
    libpng warning: iCCP: known incorrect sRGB profile
    pycharm中导入pygame库失败及解决办法
    pycharm中导入pygame等第三方库
  • 原文地址:https://www.cnblogs.com/crbhf/p/15087525.html
Copyright © 2011-2022 走看看