如何手動釋放Python的記憶體

2021-06-29 05:24:10 字數 3198 閱讀 4104

在上篇部落格中,提到了對乙個指令碼進行的多次優化。當時以為已經優化得差不多了,但是當測試人員測試時,我才發現,踩到了python的乙個大坑。

在上文的優化中,對每500個使用者,會進行一些計算並記錄結果在磁碟檔案中。原本以為這麼做,這些結果就在磁碟檔案中了,而不會再繼續占用記憶體;但實際上,python的大坑就是python不會自動清理這些記憶體。這是由其本身實現決定的。具體原因網上多有文章介紹,這裡就不copy了。

本篇部落格將貼乙個筆者的實驗指令碼,用以說明python確實存在這麼乙個不釋放記憶體的現象,然後提出乙個解決方案,即:先del,再顯式呼叫gc.collect().

指令碼和具體效果見下。

實驗環境一:win 7, python 2.7

from time import sleep, time

import gc

def mem(way=1):

print time()

for i in range(10000000):

if way == 1:

pass

else: # way 2, 3

del i

print time()

if way == 1 or way == 2:

pass

else: # way 3

gc.collect()

print time()

if __name__ == "__main__":

print "test way 1: just pass"

mem(way=1)

sleep(20)

print "test way 2: just del"

mem(way=2)

sleep(20)

print "test way 3: del, and then gc.collect()"

mem(way=3)

sleep(20)

執行結果如下:

test way 1: just pass

1426688589.47

1426688590.25

1426688590.25

test way 2: just del

1426688610.25

1426688611.05

1426688611.05

test way 3: del, and then gc.collect()

1426688631.05

1426688631.85

1426688631.95

對於way 1和way 2,結果是完全一樣的,程式記憶體消耗峰值是326772kb,在sleep 20秒時,記憶體實時消耗是244820kb;

對於way 3,程式記憶體消耗峰值同上,但是sleep時記憶體實時消耗就只有6336kb了。

實驗環境二: ubuntu 14.10, python 2.7.3

執行結果:

test way 1: just pass

1426689577.46

1426689579.41

1426689579.41

test way 2: just del

1426689599.43

1426689601.1

1426689601.1

test way 3: del, and then gc.collect()

1426689621.12

1426689622.8

1426689623.11

ubuntu@my_machine:~$ ps -aux | grep test_mem

warning: bad ps syntax, perhaps a bogus '-'? see

ubuntu 9122 10.0 6.0 270916 245564 pts/1 s+ 14:39 0:03 python test_mem.py

ubuntu 9134 0.0 0.0 8104 924 pts/2 s+ 14:40 0:00 grep --color=auto test_mem

ubuntu@my_machine:~$ ps -aux | grep test_mem

warning: bad ps syntax, perhaps a bogus '-'? see

ubuntu 9122 10.0 6.0 270916 245564 pts/1 s+ 14:39 0:03 python test_mem.py

ubuntu 9134 0.0 0.0 8104 924 pts/2 s+ 14:40 0:00 grep --color=auto test_mem

ubuntu@my_machine:~$ ps -aux | grep test_mem

warning: bad ps syntax, perhaps a bogus '-'? see

ubuntu 9122 11.6 0.1 30956 5608 pts/1 s+ 14:39 0:05 python test_mem.py

結論:以上說明,當呼叫del時,其實python並不會真正release記憶體,而是將其繼續放在其記憶體池中;只有在顯式呼叫gc.collect()時,才會真正release記憶體。

進一步:

while ((1)); do ps -aux | sort -n -k5,6 | grep my_script; free; sleep 5; done

結果發現:記憶體並不會在每500個使用者一組執行完後恢復,而是一直持續消耗到僅存約70mb時,gc才好像起作用。本環境中,機器使用的是cloud instance,總記憶體2g,可用記憶體約為1g,本指令碼記憶體常用消耗是900m - 1g。換句話說,對於這個指令碼來說,gc並沒有立即起作用,而是在系統可用記憶體從1 - 1.2g下降到只剩70m左右時,gc才開始發揮作用。這點確實比較奇怪,不知道和該指令碼是在thread中使用的gc.collect()是否有關,或者是gc發揮作用原本就不是可控的。筆者尚未做相關實驗,可能在下篇部落格中繼續**。

但是,可以肯定的是,若不使用gc.collect(), 原指令碼將會將系統記憶體耗盡而被殺死。這一點從syslog中可以明顯看出。

如何手動釋放Linux記憶體的方法

當在linux下頻繁訪問檔案後,物理記憶體會很快被用光,當程式結束後,記憶體不會被正常釋放,而是一直作為caching。這個問題,貌似有不少人在問,不過都沒有看到有什麼很好解決的辦法。那麼我來談談這個問題。proc是乙個虛擬檔案系統,我們可以通過對它的讀寫操作做為與kernel實體間進行通訊的一種手...

linux 手動釋放記憶體

當在linux下 頻繁訪問檔案 或者 程式測試頻繁崩潰後,物理記憶體會很快被用光,當程式結束後,記憶體不會被正常釋放,而是一直作為caching 因此我們很有必要手動清理系統快取釋放記憶體。我們在清理快取前應該先 sync下 因為系統在操作的過程當中,會把你的操作到的檔案資料先儲存到buffer中去...

linux手動釋放記憶體

當在linux下頻繁訪問檔案後,物理記憶體會很快被用光,當程式結束後,記憶體不會被正常釋放,而是一直作為caching。這個問題,貌似有不少人在問,不過都沒有看到有什麼很好解決的辦法。那麼我來談談這個問題。proc是乙個虛擬檔案系統,可通過對它的讀寫操作做為與kernel實體間進行通訊的一種手段。也...