内存池技术
内存池技术是一种饱受争议的技术
争议热点在于到底有没有必要自己实现。
1.内存池技术出现在libc尚不成熟的时候,当时程序经常在运行一段时间后性能下降,当时维护内存池很有必要
2.现在64位服务器经常是32G以上的内存,管理内存碎片意义不打
3.写malloc的各位都是大神,自己写有99%的可能会更差,更何况现在还有tmalloc、jmalloc等与时俱进的内存管理库。
4.内存数据库等以内存为主的服务器程序可以自己管理内存来达到某些特殊的公平,比如性能才是我们认为的供公平,浪费内存是可以接受的,诸如此类有特殊公平需求的。
内存池的实现方案
1.FreeList
STL的二级内存配置器就是FreeList
2.slab
memcached的内存管理方案
FreeList实现方案
一句话描述:用链表把待释放的内存保存起来重复利用。
STL的二级配置器实现的部分内容:
free_list
保存已释放内存的数据,每一个项都包含一个指向固定大小的区块的单链表指针,指针指向可重复利用内存list,区块的大小是随着下标递增的:8、16、24、32、40、48、56、64、72、80、88、96、104、112、120、128。
memory pool
内存池,当free_list找不到可重复利用的内存时就向memory pool申请,通过内存池申请内存时会申请20*size的内存,返回第一块size内存给客户,其他的19个size内存添加到free_list对应下标的可回收利用区块链表。
memory pool的内存来源
维护start和end两个指针表示当前的水位,水位充足时直接分配内存给客户。
水位不足时malloc2*20*size+fixed_size的长度,20*size用于返回客户和加入free_list,其他的留在内存池中。
STL的二级内存配置器目的
回收利用小于等于128字节的小内存,避免内存碎片。
slab实现方案
memcached的实现方案 ![](https://images2015.cnblogs.com/blog/526751/201607/526751-20160719142405982-186900195.png)
![](https://images2015.cnblogs.com/blog/526751/201607/526751-20160719142405982-186900195.png)
slabclass是一个全局数组
slabclass中的slab的size按照配置的factor因子递增
slabclass的slab_list包含的slab大小都是一样的
回收的slab加入slots
申请新的slat的时候优先利用slots中的可回收内存。
以上slab的设计可以在源码slabs.c中查看详细,从slabs_init开始是一个不错的主意。
item和这里的关系并不大,是申请内存的客户用的。