2013-11-21 22 views
21

完成工作測試用例如何避免[錯誤12]無法分配因使用子模塊

當然這取決於在本地和遠程計算機的數組的大小會有所不同內存的內存錯誤。

z1 = numpy.random.rand(300000000,2); 
for i in range(1000): 
    print('*******************************************\n'); 
    direct_output = subprocess.check_output('ssh [email protected] "ls /"', shell=True); 
    direct_output = 'a'*1200000; 
    a2 = direct_output*10; 
    print(len(direct_output)); 

當前使用情況

萬一它有助於我的使用情況如下:

我問題,那麼數據庫查詢生成的表存儲在遠程機器上。然後我想通過網絡傳輸它們並進行分析。到目前爲止,我一直在做這樣的事情在Python的情況如下:

#run a bunch of queries before hand with the results in remote files 

.... 
counter = 0 
mergedDataFrame = None 
while NotDone: 
    output = subprocess.check_output('ssh [email protected] cat /data/file%08d'%(counter)) 
    data = pandas.read_csv(...) 
    #do lots of analysis, append, merge, numpy stuff etc... 
    mergedDataFrame = pandas.merge(...) 
    counter += 1 

在某些時候,我收到的check_output命令以下錯誤:[錯誤12]無法分配內存

背景

感謝以下問題,我想我有一個什麼是錯的想法。發佈了一些解決方案,我試圖確定哪些解決方案可以避免[Errno 12]無法分配與使用fork/clone的子流程實現相關的內存錯誤。

Python subprocess.Popen "OSError: [Errno 12] Cannot allocate memory"這給了潛在的診斷,並提出了一些解決辦法像產卵單獨的腳本等等...

Understanding Python fork and memory allocation errors建議使用rfoo規避叉/克隆和產卵子進程的子進程限制和複製存儲等..這似乎意味着一個客戶端服務器模型

What is the simplest way to SSH using Python?,但我有額外的限制,我不能使用子進程由於內存限制和fork /克隆實現?解決方案建議使用paramiko或其上的東西,其他人建議子進程(我發現它不會在我的情況下)。

還有其他類似的問題,但答案經常討論的文件描述符是罪魁禍首(在這種情況下,他們不是),增加更多的RAM(系統無法這樣做),升級到x64(我已經在64)。一些暗示ENOMEM的問題。一些答案提到,試圖確定subprocess.Popen(在我的例子中是check_output)是否沒有正確地清理進程,但看起來像S. Lott和其他人一致認爲子進程代碼本身正在清理。

我經歷的源代碼搜索在GitHub https://github.com/paramiko/paramiko/search?q=Popen&type=Code和它出現在proxy.py文件中使用的子進程。

實際問題

這是否意味着最終的paramiko使用上面描述的,當蟒蛇內存佔用量的增長和重複POPEN通話之前,將有問題的POPEN解決由於克隆/前叉實施?

如果paramiko不起作用有另一種方法來做我正在尋找與客戶端唯一的解決方案?或者需要客戶/服務器/套接字解決方案?如果是的話,任何rfoo,龍捲風,或zeromq,http傳輸工作在這裏?

筆記 我正在運行64位linux 8GB主內存。我不想追求購買更多RAM的選擇。

+0

1.我可以使用[簡單示例](https://gist.github.com/7637011)重現此問題。 (64位linux)2.通常我會希望'paramiko'使用套接字來創建連接。 – jfs

+0

您是否嘗試過[如何在python中scp?](http://stackoverflow.com/q/250283/4279) – jfs

+0

我確實看到了該鏈接,謝謝。他們似乎主要建議paramiko。 Paramiko(通過套接字)應該繞過子進程模塊的fork/clone問題是否正確?我與paramiko主要關心的(可能是錯誤的)是我做了一個快速的源代碼搜索,並且看到它使用了子進程模塊 - 儘管我不知道什麼程度或者程度如何。 – Paul

回答

1

如果內存不足,可能是因爲子進程試圖同時讀取太多內存。除了使用重定向到本地文件之外,該解決方案可能使用類似popen的功能,並且可以一次讀取一個stdin/stdout對。

+0

中的分叉/克隆不,這不是因爲子流程在內存中讀取太多。這些文件只有200-300MB。請閱讀發佈的鏈接,特別是第一個鏈接以查看問題。它與子進程的實現方式有關:fork/clone。 http://stackoverflow.com/questions/1367373/python-subprocess-popen-oserror-errno-12-cannot-allocate-memory – Paul

+0

Linux fork/clone在寫入時複製。它不應該使用大量的實際內存,除非您的交換策略不允許overcommit。對於CPython而言,美中不足的是,CPython的引用計數遍佈整個地方,很快就會使頁面變髒,需要複製。 – dstromberg

+0

如果你想出了一個帶有適當的輸入和預期輸出的http://sscce.org/,我會有興趣更深入地研究這個問題。我試過:output = subprocess.check_output(['ssh','localhost','cat','/ etc/services']) ,但它沒有重現這個問題。 – dstromberg

相關問題