2011-03-01 42 views
0

アプリケーションの詳細:pyQtアプリケーション、Qt 4.4、Python 2.5余分なガベージコレクション?

問題:長時間(アプリケーションを使用して長時間閉じる)、アプリケーションが遅くなることがあります。私はプロファイリングアプリケーションのほとんどを試しましたが、問題を指摘するのに重要なものは見つかりませんでした。

私のアプリケーションは、QTabWidgetを使用して異なるタブに複数のテーブルを作成します。ですから、タブの切り替えを高速化するためには、テーブルを一度しか構築せず、QTableWidgetItemをメモリに保持しておきます。 QTableWidgetItemの数は〜5000 - 10000の範囲です。変更されるまで、構築され、メモリに保持される必要のあるオブジェクト(#〜600 - 800)がさらにあります。

GCがアプリケーションを時々遅くする可能性があると私は考えていました。デフォルトのGCしきい値は700,10,10です。私の場合、700は非常に少ないようです。これらのQTableWidgetItemは、データが変更されるまでメモリに残ります。だから、GCはフェーズ1、フェーズ2、フェーズ3で頻繁に蹴られることがありますか? データが変更されたら、mytable.setRowCount(0)を実行してデータを参照解除するだけです。この場合、メモリを再利用するためにGCは必要ありません。私は正しい?

これらのオブジェクトの一部を追跡しないようにGCに指示できますか?

私の理解が間違っているとお考えですか?

質問が不明な場合はお知らせください。

def fetchData (self, win=None): 
"""Fetches data from the data sources. 
    """ 
start = time.clock() 
changed = self.adjustDateRange() 
if not changed and self.chartEdition == self.fetchEdition: return 

badIngredients = [] 
ingredientList = self.getIngredientList() 
parentWin = win 
if parentWin is None: 
    parentWin = qApp.activeWindow() 

B = 0 
N = len(ingredientList) 
if N == 0: return 

    progress = QProgressDialog(parentWin) 
    progress.setWindowModality(Qt.WindowModal) 
progress.setWindowTitle ("FetchData Progress") 
progress.setRange (0, N) 
    #progress.forceShow() 
self.lock() 
try: 
    for i in xrange(len(ingredientList)): 
    progress.setValue(i) 
    if B > 0: 
     progress.setLabelText("Fetching time series %s of %s\n"\ 
        "Number of missing series: %s" % \ 
        (i+1,N,B)) 
    else: 
       progress.setLabelText("Fetching time series %s of %s" % \ 
        (i+1,N)) 
       print self, "Fetching time series ", i+1, " of ", N 
    qApp.processEvents() 
    ingredient = ingredientList[i] 
    if progress.wasCanceled(): 
     for ingredient in ingredientList[i:len(ingredientList)]: 
     ingredient.error = 1 
     badIngredients.append(ingredient) 
     break 
    try: 
     ingredient.getTimeSeries (win) 
     ingredient.error = 0 
    except: 
     #Handle Exception here 
       # Create a badIngredient list here 
    for ingredient in badIngredients: 
    self.deleteIngredient(ingredient) 
finally: 
    progress.setValue(N) 
     progress.close() 
    self.callWhenFree (self, self.chartChanged, remove=True) 
    self.unlock() 
    self.emit (SIGNAL("dataChanged")) 
self.fetchEdition = self.chartEdition 
end = time.clock() 
print "Data Fetched in %s sec" %(end-start) 

EDIT:進捗ダイアログが遅く、遅くなって続けて時間をかけて、このループを実行中。しかし、これらのデータとより多くのQtオブジェクトのために巨大なテーブルを作成するようなことが起こっています。また、QGraphicsItemのグラフ描画が遅くなります。現在、 qApp.processEvent()をテスト目的でコメントしました。QtのバグリストでQProgressDialog.setValueが内部的にprocessEventsを呼び出しているため、明示的に呼び出す必要はありません。また、アプリケーションがこの進行ダイアログでフリーズし、それを強制終了する必要がある、凍結の問題があります。

私はこれは、私が漏れする可能性のあるコードを実行した後、初めて

tuple      16243 
dict      6325 
function     4220 
instance     3814 
QTreeWidgetItem   2849 
wrapper_descriptor   2642 
weakref     1447 
getset_descriptor   1387 
list      934 
method_descriptor   815 
builtin_function_or_method 805 
wrappertype    660 
type      652 
classobj     267 
module      235 
member_descriptor   181 
QAction     154 
instancemethod    47 
property     36 
frame      34 
QWidget     33 
QColor      33 
QVBoxLayout    27 
_Condition     20 
QLabel      18 
QMenu      17 
QToolButton    14 
QTableWidgetItem   13 
QGridLayout    13 
SplitResult    13 
QTimer      11 
TypeInfo     10 
classmethod_descriptor  10 
QComboBox     9 
QLineEdit     9 
QCheckBox     9 
QSpacerItem    8 
QGroupBox     7 
PenStyle     6 
set      6 
ChartViewAction   6 
QHBoxLayout    6 
MouseButton    6 
QRadioButton    5 
QActionGroup    5 
QtMsgType     5 
Thread      4 
QPushButton    4 
QToolBar     4 
staticmethod    4 

のためのアプリケーションを開いたときに、私が何を得る最も上位であるメモリ で最も上位50のオブジェクトを取得するためにhttp://mg.pov.lt/objgraph/をobjgraph使用しましたメモリ内に30個のオブジェクトがあります。

tuple      19948 
QTableWidgetItem   9298 
dict      7562 
function     4220 
instance     4157 
QTreeWidgetItem   2849 
wrapper_descriptor   2788 
QGraphicsRectItem   2246 
weakref     1527 
getset_descriptor   1392 
list      1198 
QGraphicsLineItem   825 
method_descriptor   816 
QGraphicsTextItem   812 
builtin_function_or_method 811 
QColor      780 
DQEllipse     748 
wrappertype    660 
type      652 
QAction     280 
classobj     267 
module      235 
member_descriptor   189 
instancemethod    110 
dqComboBoxTableItem  66 
property     36 
frame      35 
QWidget     33 
QVBoxLayout    27 
GlobalColor    24 

QTableWidgetItemsは、メモリ内になければなりません。現在、gcを無効にしてこのアプリケーションをテストしています。私が見ているオブジェクトのほとんどは、QGraphicsLineItem、QGraphicsRectItemなどのように作成され、メモリ内に保持されます。新しいオブジェクトを作成すると、これらのオブジェクトは新しいオブジェクトでオーバーライドされ、古いオブジェクトが参照解除されます。 メモリリークをテストする他の手段は何ですか?

gc.disable() 

またはより良いまだ:あなたがして、あなたの理論をテストするために、ガベージコレクションをオフにしてみてください可能性があり

+0

これはgcの問題よりもリークのような臭いがあります。私たちにいくつかのコードを教えてくれますか? – goertzenator

答えて

0

gc.set_debug(gc.DEBUG_LEAK) 

は、より多くのためのPythonの参照にthe relevant pageを参照してください。