librdkafka-0.7在执行rd_kafka_destroy后,内存泄露

1. 走读librdkafka-0.7的代码, 发现其destroy后,有内存泄露的问题;


 2. 验证:通过 1000000次,创建kafka实例,释放实例;
  即rk=rd_kakfa_new(); 然后rd_kafka_destroy(rk); 内存耗尽,导致程序退出;


 3. 问题原因:
    rk实例选用引用计数的思想来释放其资源;
   对于生产者,其将引用计数设置为2:一个为为主线程(生产者线程); 一个发送线程 (消费者线程, 主线线程pthread_create 所得);
   由于两者通过 互斥锁+条件变量,实现共享一个queue,实现数据的同步;
   
   其通信模型:
   1. 在rd_kafka_new中创建了消费者线程, 此时queue为空, 消费者线程阻塞pthread_cond_wait(); 
   2. 生产者线程,每生产一个砖头,将砖头放进queue中,同时通过pthread_cond_signal 通知消费者线程;
   3. 消费线程, 如果发现queue不为空,就去消费queue中砖头,直到queue为空,阻塞在pthread_cond_wait();
   4. 消费者线程收到生产者的signal信号,转3.
  
    
  
   问题,生产线程主动执行rd_kafka_destroy时,只能将引用计数减1,等待消费者线程主动退出;
    此时有两个问题:
    1. 消费者线程阻塞,永远不会退出,导致内存+pthread资源泄露;
    2. 如果运气比较好,消费者线程恰好也退出了,但是,原有destroy并没有pthread资源的回收机制,pthread_join,回收pthread的资源,
       如果,作为一个常态服务进程,如果不定期出现rd_kafka_new/destroy, 同样会导致资源泄露(内存泄露);


  解决方法:
   1.rdkafka的资源释放全部由生成者线程完成:通过调用rd_kafka_destroy:
     1. 首先将rk的应用计数 - 1, 看消费者线程是否退出,
     2. 如果消费者线程已退出,直接执行资源回收的任务;
     3. 如果消费者线程还在,此时消费者线程肯定阻塞在了pthread_cond_wait, 
        故生产者线程向其发送信号,使消费线程退出,同时引用计数减少1;转2;




  此外,值的注意的一点是,pthread_join 回收子线程的处理只能在父线程里处理;


 验证:

   验证:通过 1000000次,创建kafka实例,释放实例;无内存泄露的问题;


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值