python的c/c++扩展内存泄露bug fix

近日需要使用到某同学使用c++封装的python扩展模块,搭配好环境,写上代码,跑起来,top一下,发现内存一直在涨。。。

于是找到源代码,大致瞅了下,发现貌似是一些引用计数的问题

py的封装最不好控制的就是引用计数了,很多时候不知道啥时候Py_INCREF,啥时候Py_DECREF,这也是为什么会存在 boost.python,pycxx的原因,诸如boost.python,pycxx的模块把这些问题都给隐藏了

ok,现在开始验证,在调用的py代码里面加上:

print len(gc.get_objects())

把程序run起来,发现数目一直在涨,目前可以确定:内存确实存在泄露。下一步,定位是哪里泄露。

看代码,发现返回结果的时候,是打包成了一个新的result结构体,把这个结构体注释掉,仅仅调用segment函数,重新编译,仍然有泄露。

看来问题不是在result结构体,研究segment的代码,发现里面的核心功能就是一个切词,把获取切词结果的函数注释掉,发现仍然有问题。

于是怀疑是使用的切词的库有问题,如果找到所使用的版本,发现这个的四位版本list中确实有个版本fix了内存泄露的问题,那么问题很明显了:使用了一个内存泄露的c库。

心中一阵狂喜,嗯嗯,问题应该可以解决了。

于是更新所使用的c库,重新build出so,跑上py代码,top下观看内存,咦,怎么内存还是一直在涨而object不变?

很奇怪,object数目不变,就表示没有内存泄露,但是内存却一直在涨。。。

怀疑是代码写的不对,于是改用了两种方法来做:

1,把写的c扩展的代码,改用类实现

2,写个c的简单的封装,调用py的ctypes来使用这个so

写完后验证了下,发现object仍然不变,但内存一直在涨。这说明:

1,内存没泄露---否则object数目会一直增长

2,很可能是py自己获取了内存后,就一直未释放(这里的未释放不是指不会释放该对象,而是指不会释放管理这个对象的object指针)

google了下,发现很多人都曾验证过,py确实如此,比如 这里 ,另外,这里 也有一篇文章说为什么py不释放内存。

于是想,好了,事情到此为止了,好歹有个交代了。于是准备放弃研究这个问题,把其归为py自己的内存管理的问题:py自己的pool中获取到内存就不会释放。

原本以为事情就到此可以结束

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值