2

Python 2.7、wxPython 2.8.12.1、および Windows 7 を実行しています。

大きなデータ オブジェクトを wx.Frame に渡し、インタラクティブなプロットを作成するプログラムに取り組んでいます。目標は、データ オブジェクトごとに新しいウィンドウとプロットを作成して、多くのデータ オブジェクトを反復処理することです。

私が遭遇した問題は、wx.Frame サブクラスの新しいインスタンスごとに、メモリ使用量が劇的に増加することです。

以下のコードは私の問題を再現します。

最初のループは 10 個のオブジェクトを作成し、それぞれにサイズが減少する配列が含まれます。このループが実行されると、メモリ使用量 (Windows タスク マネージャーによる) が反復ごとに低下します。

2 番目のループは、同じ配列を保持する 10 個の wx.Frame オブジェクトを作成します。ただし、現在、メモリ使用量は 1 GB まで着実に増加しています。

import numpy as np
import time
import wx


class MyClass():

    def __init__(self, i):
        self.x = np.arange(0, i*5000000)


#While this loop runs, memory usage decreases
for i in [10,9,8,7,6,5,4,3,2,1]:
    print(i)
    m = MyClass(i)
    time.sleep(2)


class wxWindow(wx.Frame):

    def __init__(self,i = None):
        super(wxWindow,self).__init__(None)
        self.x = np.arange(0, i*5000000)


#While this loop runs, memory usage increases
#until the program crashes.
for i in [10,9,8,7,6,5,4,3,2,1]:
    print(i)
    app = wx.App()
    app.frame = wxWindow(i)
    app.frame.Show(True)
    app.MainLoop()
    app.Destroy()

2 つの方法でメモリ リークを止めることができます。

1) 変数 "x" をローカルにする (つまり、"self." を削除する):

x = np.arange(0, i*5000000)

2) 弱参照の使用:

self.x = weakref.ref(np.arange(0, i*5000000))

クラス全体で大きなデータ オブジェクトを使用できるようにする必要があるため、方法 1 は使用できません。私はweakrefオブジェクトについてまったく知りませんが、これまでのところ、データオブジェクトへの弱参照を使用して運がなかった(常に「weakrefオブジェクトには属性がありません」というエラーが発生します)。

4

2 に答える 2

1

コードの最後の部分を次のように変更します。

app = wx.App()
for i in [10,9,8,7,6,5,4,3,2,1]:
    print(i)
    frame = wxWindow(i)
    frame.Show(True)
    app.MainLoop()

wx.App はシングルトンとして動作するため (このスレッドを読んでください)、プロセスごとに必要な wx.App インスタンスは 1 つだけです。あなたはそれらを10個作っていました。とにかく、これはあなたのメモリの問題を解決します。

于 2013-04-30T00:08:13.950 に答える
0

xクラス属性を作成できるようです

class wxWindow(wx.Frame):
    x = np.arange(0, i*5000000)
    def __init__(self, i=None):
        super(wxWindow, self).__init__(None)

別の方法は、明示的にすることですdel x

del app.frame.x

最後に、おそらくクリーンアップを処理できる wxWindow のメソッドがあります。例えば

class wxWindow(wx.Frame):

    def __init__(self,i=None):
        super(wxWindow, self).__init__(None)
        self.x = np.arange(0, i*5000000)

    def close(self):  # you'll have to find the correct name in the docs
        del self.x
        super(wxWindow, self).close()
于 2013-04-29T23:14:48.800 に答える