[Python] 使用 valgrind 偵測 python 的 memory leak
最近又開始查專案的 python 程式 memory leak 的問題,
真是有種陰魂不散的感覺…
python 的的記憶體管理是程式本身無法插手的,
原本是想拿 debug C/C++ 程式時常用的 valgrind 來查查看 python 的 leak,
不過後來發現其實不需要,用 python 的 gc 來查就可以了,
valgrind 只有查自己寫 python 的 C/C++ 模組時才比較可能會用到…
不過還是記錄一下步驟吧~
1. 將 python 編譯成支援 valgrind 的版本
要讓 python 能正確支援 valgrind,需要將 python 加上參數重新編譯,
首先安裝 valgrind-devel (待會編譯 python 時會需要):
yum install valgrind-devel
接著下載 python 的原始碼來編譯~
下面我是下載了 python 2.7.5 的原始碼,將安裝路徑指到 /tmp/python_dbg,
重點是要加上 –with-pydebug –without-pymalloc –with-valgrind 等參數:
–with-threads: Enable thread support
–with-pydebug: Build with Py_DEBUG defined (可以使用 Python 的除錯環境變數)
–without-pymalloc: Disable specialized mallocs
–with-valgrind: Enable Valgrind support
wget wget https://www.python.org/ftp/python/2.7.5/Python-2.7.5.tgz
tar zxvf Python-2.7.5.tgz
cd Python-2.7.5
./configure --prefix /tmp/python_dbg --with-threads --with-pydebug --without-pymalloc --with-valgrind
make
make install
2. 下載給 valgrind 用的 python 白名單
用編譯好的 python 執行程式時,valgrind 會顯示非常多的 possible leak/definite leak,
但(應該)有蠻大一部分是誤判,所以可以下載一個白名單的檔案來排除:
http://svn.python.org/projects/python/trunk/Misc/valgrind-python.supp
3. 使用 valgrind 執行 python 程式
最後,就是使用 valgrind 了~
照平常使用 valgrind 的方式,加上 –leak-check=full 參數顯示完整的 memory leak 資訊,
再加上 –suppressions 參數來指定我們下載下來的白名單,
就能執行 python 程式並在最後顯示出 leak 的部分了:
valgrind --leak-check=full --suppressions=valgrind-python.supp /tmp/python_dbg/bin/python test.py
由於我的 python 程式 leak 的部分事實上是 python object 有 cyclic reference,
因此 valgrind 的結果裡面只會看到一堆像 PyObject 之類的東西,
沒辦法看出來問題在哪裡…
不過如果是 python 程式裡有呼叫到 C/C++ 模組的部分,倒是有顯示出可能的 leak 點~
因此如果是用來除錯給 python 用的 C/C++ 模組的話,這方法應該是可以用的囉~