「イベント」を生成するイテレータ/ジェネレータがあります。イベントは、名前、タイムスタンプ、および値で構成されます。それらをNumPy配列に保存したい。これはで行われ_LoadTriples()
ます:
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
あり、ユーザーが反復を中止したときに通知するイベントです。self.allEvents
空のリストです。ここで、NumPy 配列に Triples を追加します。(name, timestamp, value).
反復を中断する可能性が必要で、中断できないため、配列のリストですnumpy.fromiter
。したがって、約 0.3 秒ごとに反復を停止できます。
それはすべてうまくいきます。しかし、ある例では、Python がリスト用に 300MB のメモリをすぐに使い切ってしまうことがあります。繰り返しを停止すると、いつ停止したかにもよりますが、リストに必要なのは最大10 MBだけですが、self.allEvents.append(np.fromiter(...))
300MBへの呼び出しが数回使用された後、その理由がまったくわかりません。
self.allEvents
さらに、このメモリは、その関数の呼び出しの直後に削除しても、プログラム全体を停止するまで解放されません。私がそれをリリースするのを妨げるいくつかの参照があるに違いありません. どのオブジェクトがリストへの参照を持っているかを確認する方法はありますか?
言及すべきもう1つのこと:関数は new として呼び出されますthreading.Thread
が、メインスレッドはそれを待ちます...
編集:私は言及しませんでした.300MBが使用されると、リストが大きくなってもメモリは割り当てられません。リストは、いくつかの追加後にこのメモリを予約しているようです。