2016-04-07 48 views
2

我想處理一個3GB的XML文件,並在讀取文件並在字典中存儲一些數據的循環中獲取內存錯誤。創建大型字典的Python內存錯誤

class Node(object): 
    def __init__(self, osmid, latitude, longitude): 
     self.osmid = int(osmid) 
     self.latitude = float(latitude) 
     self.longitude = float(longitude) 
     self.count = 0 


context = cElementTree.iterparse(raw_osm_file, events=("start", "end")) 
context = iter(context) 
event, root = context.next() 

for event, elem in context: 
    if event == "end" and elem.tag == "node": 
     lat = float(elem.get('lat')) 
     lon = float(elem.get('lon')) 
     osm_id = int(elem.get('id')) 
     nodes[osm_id] = Node(osm_id, lat, lon) 
     root.clear() 

我正在使用迭代解析方法,所以問題不在於讀取文件。我只是想將數據存儲在字典中供以後處理,但似乎字典變得太大了。後來在程序中我讀了鏈接,並且需要檢查鏈接引用的節點是否在最初的一批節點中,這就是爲什麼我將它們存儲在字典中的原因。我怎麼能夠大大減少內存佔用(腳本甚至沒有接近完成,所以剃掉碎片和碎片不會有多大幫助),或者大大增加可用於python的內存量?監控內存使用情況,它看起來像蟒蛇大約在1950 MB,我的電腦仍然有大約6 GB的RAM。

+2

您是否正在運行64位Python? –

+0

哦拍攝,我以爲我只是檢查,而我實際上是在使用32.這是我的理解,有32內存使用硬限制,但沒有64,對不對? – wmebane

+1

還有一個64位的硬盤上限,但你不太可能觸及它,因爲它的容量是千兆字節的倍數。 –

回答

3

假設您創建了大量的Node s,您可以考慮使用__slots__爲每個Node預定義一組固定屬性。這消除了存儲每個實例__dict__的開銷(以防止創建未聲明的屬性),並且可以輕鬆地將內存使用量減少約5倍(less on Python 3.3+ where shared key __dict__ reduces the per-instance memory cost for free)。

這很容易做到,只需更改的Node的聲明:

class Node(object): 
    __slots__ = 'osmid', 'latitude', 'longitude', 'count' 

    def __init__(self, osmid, latitude, longitude): 
     self.osmid = int(osmid) 
     self.latitude = float(latitude) 
     self.longitude = float(longitude) 
     self.count = 0 

例如,關於Python 3.5(其中共享密鑰字典已經保存你的東西),在目標頭頂的差異可以用可見:

>>> import sys 
>>> ... define Node without __slots___ 
>>> n = Node(1,2,3) 
>>> sys.getsizeof(n) + sys.getsizeof(n.__dict__) 
248 
>>> ... define Node with __slots__ 
>>> n = Node(1,2,3) 
>>> sys.getsizeof(n) # It has no __dict__ now 
72 

請記住,這是帶有共享密鑰字典的Python 3.5;在Python 2中,每個實例的成本__slots__會類似(一個指針大小的變量更大的IIRC),而沒有__slots__的成本會增加幾百個字節。

此外,假設您使用的是64位操作系統,請確保您安裝了64位版本的Python以匹配64位操作系統;否則,Python將被限制在〜2 GB的虛擬地址空間,而你的6 GB內存非常少。

+0

這很好!削減內存使用噸和切換到64位版本給我額外的GB,我仍然需要。謝謝! – wmebane