设为首页 收藏本站
查看: 1327|回复: 0

[经验分享] GlusterFS之内存池(mem-pool)使用实例分析

[复制链接]

尚未签到

发表于 2019-2-1 13:14:23 | 显示全部楼层 |阅读模式
  上一篇博客详细分析了GlusterFS之内存池的实现技术,今天我们看看GlusterFS是怎么使用这个技术的。
  第一步:分配和初始化:
  cli进程在初始化的过程中会涉及到内存池的建立和初始化,具体涉及到内存池初始化的代码如下(在cli.c文件中的glusterfs_ctx_defaults_init函数):
  [cpp] view plaincopyprint?

  •   /* frame_mem_pool size 112 * 64 */
  •   pool->frame_mem_pool = mem_pool_new (call_frame_t, 32);//为调用针对象分配内存池对象,对象类型是call_frame_t,32个这样的内存块
  •   if (!pool->frame_mem_pool)
  •   return -1;

  •   /* stack_mem_pool size 256 * 128 */
  •   pool->stack_mem_pool = mem_pool_new (call_stack_t, 16);//为调用堆栈对象分配内存池对象,对象类型是call_stack_t,16个这样的内存块

  •   if (!pool->stack_mem_pool)
  •   return -1;

  •   ctx->stub_mem_pool = mem_pool_new (call_stub_t, 16);
  •   if (!ctx->stub_mem_pool)
  •   return -1;

  •   ctx->dict_pool = mem_pool_new (dict_t, 32);
  •   if (!ctx->dict_pool)
  •   return -1;

  •   ctx->dict_pair_pool = mem_pool_new (data_pair_t, 512);
  •   if (!ctx->dict_pair_pool)
  •   return -1;

  •   ctx->dict_data_pool = mem_pool_new (data_t, 512);
  •   if (!ctx->dict_data_pool)
  •   return -1;
  由上面的代码可以看出:集合系统中各种结构体对象可能实际会用到的数量来预先分配好,真正需要为对象内存的时候直接从这些内存池中取就可以了,用完之后又放回内存池,这样减少了分配和释放内存的额外系统开销,分配内存往往需要从用户态到内核态切换,这些都是很耗时间的,当然相同的对象还减少了初始化的时间。
  代码分配内存调用的函数是mem_pool_new,而不是在上一篇博客结束的mem_pool_new_fn函数,那是因为mem_pool_new是定义的宏函数,就是调用mem_pool_new_fn函数,函数参数分别表示对象所占内存大小、数量和名称(为分配的内存起一个名字,就是对象的名称);
  [cpp] view plaincopyprint?

  •   #define mem_pool_new(type,count) mem_pool_new_fn (sizeof(type), count, #type)
  第二步:从内存池中取出一个对象内存块:
  如下面代码取出一个调用存根的对象内存块(call_stub_t):
  [cpp] view plaincopyprint?

  •   call_stub_t *new = NULL;

  •   GF_VALIDATE_OR_GOTO ("call-stub", frame, out);

  •   new = mem_get0 (frame->this->ctx->stub_mem_pool);//从内存池中拿出一个对象内存块
  同样使用的函数不是我们介绍的mem_get,而是mem_get0函数,mem-get0封装了mem_get,做参数判断并且把需要使用的内存初始化为0,代码如下:
  [cpp] view plaincopyprint?

  •   void*
  •   mem_get0 (struct mem_pool *mem_pool)
  •   {
  •   void             *ptr = NULL;

  •   if (!mem_pool) {
  •   gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
  •   return NULL;
  •   }

  •   ptr = mem_get(mem_pool);//得到一个内存对象块

  •   if (ptr)
  •   memset(ptr, 0, mem_pool->real_sizeof_type);//初始化0

  •   return ptr;
  •   }
  第三步:放回对象内存块到内存池中:
  当我们使用完一个对象以后就会重新放回内存池中,例如还是以调用存根对象(call_stub_t)
  [cpp] view plaincopyprint?

  •   void
  •   call_stub_destroy (call_stub_t *stub)
  •   {
  •   GF_VALIDATE_OR_GOTO ("call-stub", stub, out);

  •   if (stub->wind) {
  •   call_stub_destroy_wind (stub);
  •   } else {
  •   call_stub_destroy_unwind (stub);
  •   }

  •   stub->stub_mem_pool = NULL;
  •   mem_put (stub);//放回对象内存块到内存池中
  •   out:
  •   return;
  •   }
  第四步:销毁内存池:
  如果整个内存池对象都不需要了,那么销毁掉这个内存池,实现这个功能的函数是mem_pool_destroy:
  [cpp] view plaincopyprint?

  •   void
  •   mem_pool_destroy (struct mem_pool *pool)
  •   {
  •   if (!pool)
  •   return;

  •   gf_log (THIS->name, GF_LOG_INFO, "size=%lu max=%d total=%"PRIu64,
  •   pool->padded_sizeof_type, pool->max_alloc, pool->alloc_count);

  •   list_del (&pool->global_list);//从全局内存池对象中拖链

  •   LOCK_DESTROY (&pool->lock);//销毁锁
  •   GF_FREE (pool->name);//释放名字占用的内存
  •   GF_FREE (pool->pool);//释放内存池分配的内存,就是提供给用户使用的那一段内存
  •   GF_FREE (pool);//释放内存池对象占用的内存

  •   return;
  •   }
  一般情况下内存池对象会在程序退出的时候才会释放和销毁,还有一种情况是临时分配的内存池也有可能在系统运行期间释放和销毁,因为不能保证一个预先分配的内存池就能够满足整个系统运行期间那个对象所需要的内存,可能在每一个阶段这个对象使用特别多,以至于把内存池预先分配的对象内存块使用完了,这时就需要临时分配内存池对象,过了这一段时间可能这个对象需要的个数就减少了,这时就需要释放掉临时分配的,已还给系统内存。
  OK!内存池管理技术是提供内存使用率和效率的重要手段,Glusterfs使用的内存池技术采用的是linux内核管理小内存块的分配算法slab,就是基于对象分配内存的技术。可以先去熟悉slab的原理,就能更好的理解Glusterfs的内存池技术了!


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-670479-1-1.html 上篇帖子: GlusterFS之内存池(mem-pool)实现原理及代码详解 下篇帖子: GlusterFS学习手记01
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表