2013-06-20 70 views
2

我有一個產生'事件'的迭代器/發生器。一個事件由一個名稱,一個時間戳和一個值組成。我想將它們存儲在NumPy數組中。 這是在做_LoadTriples()Python列表太大,無法刪除

def _LoadTriples(abortEvt, count=[1]): 
    it = _YieldTriples() 
    while True: 
     if abortEvt.is_set(): 
      it.close() 
      break 
     t0 = time.time() 
     self.allEvents.append(np.fromiter(it, 
             dtype=[('sigNameIdx', 'i'), 
              ('time', 'f'), 
              ('value', 'f8')], 
             count=count[-1])) 
     dur = time.time() - t0 
     if dur < 0.2: 
      count.append(count[-1]*2) 
     elif dur > 0.4 and count[-1] != 1: 
      count.append(count[-1]/2) 
     else: 
      count.append(count[-1]) 

_YieldTriples是發電機,abortEvt是當用戶abortes迭代,告訴我的事件。 self.allEvents是一個空的列表。在這裏,我想追加NumPy數組與三元組(name, timestamp, value).這是一個數組列表,因爲我想有可能打破迭代,我不能打破numpy.fromiter。所以每隔大約0.3秒我就可以停止迭代。

這一切工作正常。 但是,在一個例子中,它發生了Python迅速佔用了300MB內存的列表!當我停止迭代時,我的列表只需要最大10 MB,這取決於我什麼時候停止它,但在幾次調用self.allEvents.append(np.fromiter(...))之後,我使用了300MB,我完全不知道爲什麼。

此外,在我停止整個程序之前,即使在該函數調用後直接刪除self.allEvents,該內存也不會釋放。必須有一些防止我釋放它的參考。有什麼方法可以查看哪些對象具有對列表的引用?要提到

還有一兩件事:該功能被稱爲新threading.Thread,但mainthread等待它...

編輯:我沒有提及,沒有更多的內存分配的列表的增長,一旦使用了300MB。似乎列表會在一些附加內容後保留這些內存。

+4

我不是很積極的問題是什麼,但你使用了一個可變的默認參數。你在這裏進行的任何修改都會永久保存在你的程序中(除非你使用一些技巧來改變這個行爲)。 – mgilson

+0

定義「used」python通常不會給回內存,而是一旦獲得回收。 – seberg

+0

@mgilson:問題是分配的內存太多,我無法釋放它。從我的程序中調用了這個函數之後,我得到了MemoryError ...並且是可變的,這不是我的意圖,但也不重要,見下文。 – Jogi

回答

2

你應該嘗試:

def _LoadTriples(abortEvt, count=None): 
    if count is None: 
     count = [1] 
    ... 

易變的默認參數可能導致的問題非常快。

+1

是的,你是對的,這不是很聰明。實際上,在我的程序中我沒有任何默認參數,我只是把它放在那裏,您可以看到'count'是一個以1開始/結束的列表......但這與我的內存問題無關 – Jogi