内存池的实现

内存池的实现

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

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

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2014-04-05 23:52  mightofcode  阅读(631)  评论(0编辑  收藏  举报