簡體   English   中英

Python內存占用量與堆大小

[英]Python memory footprint vs. heap size

我在使用python腳本發出大型solr查詢時遇到一些內存問題。 我正在使用solrpy庫與solr服務器接口。 該查詢返回大約80,000條記錄。 發出查詢后,通過頂部氣球查看的python內存占用立即達到190MB。

 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND 
8225 root      16   0  193m 189m 3272 S  0.0 11.2   0:11.31 python
...

此時,通過堆查看的堆概要文件如下所示:

Partition of a set of 163934 objects. Total size = 14157888 bytes.   
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0  80472  49  7401384  52   7401384  52 unicode
     1  44923  27  3315928  23  10717312  76 str
...

unicode對象代表查詢中記錄的唯一標識符。 需要注意的一件事是,當python占用190MB物理內存時,總堆大小僅為14MB。 一旦存儲查詢結果的變量超出范圍,堆概要文件將正確反映垃圾回收:

Partition of a set of 83586 objects. Total size = 6437744 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0  44928  54  3316108  52   3316108  52 str

但是,內存占用量保持不變:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 8225 root      16   0  195m 192m 3432 S  0.0 11.3   0:13.46 python
...

為什么python的物理內存占用量和python堆的大小之間會有如此大的差異?

Python從C堆分配Unicode對象。 因此,當您分配它們中的許多(連同其他malloc塊),然后釋放除最后一個塊之外的大多數塊時,C malloc不會將任何內存返回給操作系統,因為C堆只會在最后收縮(不在中間)。 釋放最后一個Unicode對象將在C堆的末尾釋放該塊,然后允許malloc將其全部返回給系統。

除了這些問題之外,Python還維護了一組釋放的unicode對象,以加快分配速度。 因此,當釋放最后一個Unicode對象時,它不會立即返回到malloc,從而使所有其他頁面都卡住了。

CPython實現僅異常釋放分配的內存。 這是一個廣為人知的錯誤,但CPython開發人員並未對此給予太多關注。 建議的解決方法是“分叉”消耗大量RAM的進程。

您正在使用哪個版本的python?
我問是因為較舊的CPython版本沒有釋放內存,並且在Python 2.5中已修復。

我已經實現了赫魯斯克的“死而復生”的建議。 我正在使用os.fork()在子進程中執行代碼的內存密集型部分,然后讓子進程退出。 父進程在子進程上執行os.waitpid(),以便在給定時間僅執行一個線程。

如果有人發現此解決方案有任何陷阱,請發出提示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM