我正在追蹤內存不足的錯誤,並且很驚訝地發現python的多處理似乎複製了大型數組,即使我無意使用它們。爲什麼多處理複製我的數據,如果我不碰它?
爲什麼python(在Linux上)這樣做,我認爲copy-on-write會保護我免受任何額外的複製?我想象,每當我引用對象時,都會調用某種陷阱,然後纔是複製。
對於任意數據類型解決此問題的正確方法,例如30 GB的自定義詞典使用Monitor
?有沒有一些方法來構建Python,使其沒有這個廢話?
import numpy as np
import psutil
from multiprocessing import Process
mem=psutil.virtual_memory()
large_amount=int(0.75*mem.available)
def florp():
print("florp")
def bigdata():
return np.ones(large_amount,dtype=np.int8)
if __name__=='__main__':
foo=bigdata()#Allocated 0.75 of the ram, no problems
p=Process(target=florp)
p.start()#Out of memory because bigdata is copied?
print("Wow")
p.join()
運行:
[ebuild R ] dev-lang/python-3.4.1:3.4::gentoo USE="gdbm ipv6 ncurses readline ssl threads xml -build -examples -hardened -sqlite -tk -wininst" 0 KiB
的Python(或者說,CPython的)使用嵌入的對象的引用計數器。每當一個對象被傳遞給一個函數時,它的引用計數器就會增加,導致該對象被修改,從而導致子進程中的頁面錯誤。儘管如此,我不會說它解釋了你的特定示例。不過,考慮使用多線程而不是多處理。 –
@UlrichEckhardt但我沒有把任何東西傳遞給'florp'! – Mikhail
你說得對,我入侵得太早,看到我追加的最後兩句話。順便說一句:我不能在這裏重現這些問題,在Linux/x86_64上使用Python 3.4.2。 –