zoukankan      html  css  js  c++  java
  • 内存池的实现

    内存池的实现

    内存池的使用是为了解决以下两个问题:

    1 内存碎片(Fragment),内存碎片会导致分配大块内存失败

    2 malloc和free比较慢

    至于为什么会有这两个问题,或者,这两个问题真的存在吗?以后再探讨,我们先关注内存池

    在网上google一番,wiki告诉我们,内存池包括"simple memory pool"和"Region-based_memory_management",wiki还告诉我们Nigix就是用的"Region-based_memory_management",至于"simple memory pool",wiki没告诉我们去哪找代码,没事,不管了,我们直接看项目

    memcached的内存池

    memcached的内存池称为slabs,在slabs.h中声明

    slabs内存池的主要思路:

    1 按内存字节大小分chunk处理,比如增量因子为2,chunk分为8,16,32,64,如果要分配30字节的内存,则直接分配32字节的chunk

    2 一类chunk称为slabclass,每个slabclass包含一个free_list,free_list包含了当前未被使用的chunk

    3 free_list是一个链表,链表的next保存在chunk中,分配内存只需要从free_list中取一个,释放内存只需要把chunk添加到free_list中就好了

      这样使得分配和释放chunk的速度非常快

    但是有一个很蛋疼的事

    一旦分配内存后,slab就不会真正调用free()释放内存了,这样如果分配内存的请求在时间上不是均匀分布的话,那么有可能某个chunk类别下分配的内存永远不会被释放,这样

    可能出现内存不足的问题

    不过memcached也是久经考验的软件了,这个问题似乎不是很严重

    我的山寨实现:

    https://gist.github.com/mightofcode/9993607

    Nginx的内存池

    Nginx更霸气了,大内存直接分配,小内存的申请是在一个连续regin上进行,内存不够了就再来个region

    但是释放内存怎么办?

    Nginx为每个场景(以单个request为例)创建一个内存池,request完成之后销毁内存池,释放所有内存,所以Nginx的内存池在销毁整个内存池之前并不释放任何小内存

    Nginx这样做依赖一个前提:

    单个场景需要的小块内存总数不大,而且持续时间有限

    Nginx用这种办法获得了极大的提高了内存操作的速度,在vc上测试提高了100倍以上

    可见,这种实现如果要应用到自己的项目中,需要大量测试和分析

    我的山寨实现:

    https://gist.github.com/mightofcode/10002927

    结语

    内存池是个好东西,对于小块内存的分配和释放有巨大的性能提升

    参考资料

    http://www.cnblogs.com/Creator/archive/2012/04/11/2430592.html

    http://blog.csdn.net/v_july_v/article/details/7040425

  • 相关阅读:
    Google 的开源技术protobuf 简介与例子(转)
    set 学习笔记
    map 学习笔记
    网络编程-socket学习笔记
    POSIX线程_学习笔记
    shell 脚本练习
    vector 学习笔记
    用archlinux作为日常开发机的感受
    python中获取上一个月一号的方法
    golang在linux下的开发环境部署[未完]
  • 原文地址:https://www.cnblogs.com/mightofcode/p/3647753.html
Copyright © 2011-2022 走看看