2015-06-21 24 views
3

我正在追蹤內存不足的錯誤,並且很驚訝地發現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 
+0

的Python(或者說,CPython的)使用嵌入的對象的引用計數器。每當一個對象被傳遞給一個函數時,它的引用計數器就會增加,導致該對象被修改,從而導致子進程中的頁面錯誤。儘管如此,我不會說它解釋了你的特定示例。不過,考慮使用多線程而不是多處理。 –

+0

@UlrichEckhardt但我沒有把任何東西傳遞給'florp'! – Mikhail

+0

你說得對,我入侵得太早,看到我追加的最後兩句話。順便說一句:我不能在這裏重現這些問題,在Linux/x86_64上使用Python 3.4.2。 –

回答

0

的問題是,通過默認的Linux檢查最壞情況下的內存使用情況,這的確可以超過內存容量。即使python語言沒有暴露變量,情況也是如此。您需要關閉系統範圍的「overcommit」,以實現預期的COW行爲。

sysctl `vm.overcommit_memory=2' 

參見https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

2

我期望這種行爲 - 當你通過代碼到Python編寫,任何不是一個功能或對象後面守衛立即exec版進行評估。

在你的情況下,bigdata=np.ones(large_amount,dtype=np.int8)必須評估 - 除非你的實際代碼有不同的行爲,florp()沒有被調用與它無關。

要看到一個直接的例子:

>>> f = 0/0 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ZeroDivisionError: integer division or modulo by zero 
>>> def f(): 
...  return 0/0 
... 
>>> 

若要將此到您的代碼,把bigdata=np.ones(large_amount,dtype=np.int8)函數後面,由具有可用的變量調用它作爲你需要它,否則,Python是試圖將hepful在運行時給你。

如果bigdata沒有改變,你可以編寫一個函數來獲取或設置一個對象,該對象在整個過程中保持不變。

編輯:咖啡剛開始工作。當你創建一個新的進程時,Python需要將所有的對象複製到新的進程中進行訪問。您可以通過使用線程或通過一種機制,可以讓你進程之間共享內存避免這種情況,如shared memory maps或共享ctypes

+0

我試圖包裝在一個數組函數調用,但沒有骰子,或者你有其他的東西嗎?請參閱編輯。 – Mikhail

+0

我得看看你到底在做什麼。我假設'florp()'做的不僅僅是在你的實際代碼中打印。哦,其實,我只是想到了一個關於流程的重要區別,請給我第二個添加到我的答案。 – 2015-06-21 11:27:30

相關問題