我有一個產生'事件'的迭代器/發生器。一個事件由一個名稱,一個時間戳和一個值組成。我想將它們存儲在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。似乎列表會在一些附加內容後保留這些內存。
我不是很積極的問題是什麼,但你使用了一個可變的默認參數。你在這裏進行的任何修改都會永久保存在你的程序中(除非你使用一些技巧來改變這個行爲)。 – mgilson
定義「used」python通常不會給回內存,而是一旦獲得回收。 – seberg
@mgilson:問題是分配的內存太多,我無法釋放它。從我的程序中調用了這個函數之後,我得到了MemoryError ...並且是可變的,這不是我的意圖,但也不重要,見下文。 – Jogi