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-8
import os
import gc
import time
class Test:
def __init__(self):
self.name = "haha"
def run():
L = []
begin = time.time()
for i in xrange():
L.append(Test())
end = time.time()
print 'cost:%s' %(round(end-begin,))
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解釋器,其它相容性的問題有待考證。