如何解决Python2的内存泄漏问题

来源:互联网 发布:fedora与ubuntu 编辑:程序博客网 时间:2024/05/19 11:44

python进程内存撑大了下不去,只能手动重启释放内存,这么坑爹的事情你遇到过吗?哪家内存分配器强?结果一目了然。

线上进程目前都是使用原生的Python内存分配器(pymalloc),在正常的情况下表现还算稳定,但如果来了一波类似于武神坛或者天下第一的比武大会,为手机瞬间带来了10倍于平时的流量,一阵狂虐之后,Python进程占用的内存被撑大就下不去了。关于Python的内存不释放问题,可以参考一下这两篇文章:python内存不释放原理,Python memory management and TCMalloc。

为了解决内存泄漏的问题,我专门使用了三种编译方式去编译Python2.7解释器

以下分别使用pymalloc、without-pymalloc、tcmalloc测试1千万个object的list内存释放情况(注:默认使用Python2.7)。

  • 测试环境
CPU 4 QEMU Virtual CPU version 2.1.0 内存 15G 操作系统内核 Linux onlinegame-229-88 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u1 x86_64 GNU/Linux
  • 测试代码
#!/usr/bin/env python# coding: utf-8import osimport gcimport timeclass Test:    def __init__(self):        self.name = "haha"def run():    L = []    begin = time.time()    for i in xrange(10000000):        L.append(Test())    end = time.time()    print 'cost:%s' %(round(end-begin,3))    input_str = raw_input('\nrun: ')if __name__=="__main__":    print "pid:%s" %os.getpid()    input_str = raw_input('\nstart')    run()    input_str = raw_input('\nready to collect')    gc.collect()    input_str = raw_input('\ncollected.')
  • 测试结果
\ pymalloc without-pymalloc tcmalloc list对象数量 10000000 10000000 10000000 平均消耗时间 21.379s 21.199s 20.53s run调用期间内存占用 3.6g 3.6g 3.6g run结束后内存占用 2.7g 23m 8224b collect后的内存占用 2.7g 23m 8224b
  • 结论
    pymalloc在一轮暴虐之后进程内存下不去。

    不使用pymalloc容易导致不少兼容性的问题出现,而且许多python的新feature会用不了,不建议这么做。

    而tcmalloc果然名不虚传,run方法结束后,内存马上释放到解放前。建议生产环境尝试使用tcmalloc编译的Python解释器,其它兼容性的问题有待考证。

0 0