アプリケーションの詳細: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()
またはより良いまだ:あなたがして、あなたの理論をテストするために、ガベージコレクションをオフにしてみてください可能性があり
これはgcの問題よりもリークのような臭いがあります。私たちにいくつかのコードを教えてくれますか? – goertzenator