内存池的实现

内存池的实现

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

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

2 malloc和free比较慢github

至于为何会有这两个问题,或者,这两个问题真的存在吗?之后再探讨,咱们先关注内存池memcached

在网上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内存池的主要思路:google

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

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

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

  这样使得分配和释放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

相关文章
相关标签/搜索