2013-10-23 14 views
2

我已經開始使用一個相當大的模擬代碼,它需要存儲高達189383040浮點數。我知道,這很大,但沒有太多可以做到克服這個問題,比如只查看其中的一部分或逐個處理它們。Python內存錯誤使用長列表時不會發生在Linux上

我寫了一個簡短的腳本,其再現誤差,所以我可以快速地測試它在不同的環境:

noSnapshots = 1830 
noObjects = 14784 

objectsDict={} 

for obj in range(0, noObjects): 
    objectsDict[obj]=[[],[],[]] 
    for snapshot in range(0,noSnapshots): 
     objectsDict[obj][0].append([1.232143454,1.232143454,1.232143454]) 
     objectsDict[obj][1].append([1.232143454,1.232143454,1.232143454]) 
     objectsDict[obj][2].append(1.232143454) 

它代表實際的代碼的結構,其中的一些參數(2 lists長度爲3的每個和1個浮動)必須針對每個14784對象存儲在1830不同的位置。顯然這些數字每次都會有不同的對象,但在我的代碼中,我只是去了一些隨機輸入的數字。

我覺得這並不令人驚訝,它在Windows 7 Enterprise和家庭高級版上使用MemoryError時失敗。即使我在16 GB RAM的機器上運行代碼,它仍會失敗,即使機器上仍有大量內存。所以第一個問題是:爲什麼會這樣呢?我想認爲,我擁有的內存越多,我可以在內存中存儲的東西越多。

我在我的同事的Ubuntu 12.04機器上運行相同的代碼(再次使用16 GB的RAM)並且它沒有問題。所以我想知道的另一件事是:有什麼我可以做的,使Windows與此代碼感到滿意?即在堆和棧上給我的Python進程更多的內存?

終於:有沒有人有任何建議,如何以類似於在示例代碼中的方式存儲大量的數據在內存中?

編輯

的答案後,我改變了代碼:

import numpy 

noSnapshots = 1830 
noObjects = int(14784*1.3) 

objectsDict={} 

for obj in range(0, noObjects): 
    objectsDict[obj]=[[],[],[]] 

    objectsDict[obj][0].append(numpy.random.rand(noSnapshots,3)) 
    objectsDict[obj][1].append(numpy.random.rand(noSnapshots,3)) 
    objectsDict[obj][2].append(numpy.random.rand(noSnapshots,1)) 

和它的作品,儘管大量數據的情況,必須加以保存。

+3

您是否在Windows上使用64位版本的Python? – geoffspear

+0

好點。這是一個32b的Windows和64b Linux。 –

+0

將可用於Windows的RAM限制爲4GB。 – Max

回答

1

在Python中,每個float在堆上的對象,有自己的引用計數,等等。對於存儲如此多的花車,你真的應該使用花車列表的密集表示,如numpyndarray

此外,由於您正在重複使用相同的對象,因此您不能正確估計內存使用情況。您有對同一個單一對象的引用列表。在真實情況下(其中float不同),您的內存使用量會更高。你真的應該使用ndarray

+0

是的,我想過後一點。但是,無論如何,它確實會使程序拋出一個「MemoryError」,所以我認爲它對於測試的目的或多或少是好的。 –

+0

對於'numpy'數組來說並不那麼容易,因爲追加它們並不是一個真正的選擇,因爲沒有簡單的方法來做到這一點而不會導致週期性的內存跳轉。你會預先分配一個嘗試,但它可能會消耗比所需更多的內存(不是每個對象都會有最大數目的條目)。但無論如何,非常感謝您的幫助。 –

+0

@AleksanderLidtke:一個Python列表將具有與'ndarray'相同的週期性內存跳轉。 – Max

相關問題