應用程序詳細信息:pyQt應用程序,Qt 4.4和python 2.5過量垃圾收集?
問題:隨着時間的推移(使用長時間的應用程序無法關閉),應用程序有時會變慢。我嘗試了大部分分析應用程序,但沒有發現任何重要的指出任何問題。
我的應用程序使用QTabWidget在不同的選項卡中創建多個表。所以爲了加快Tab切換,我只構造一次表並將QTableWidgetItem保留在內存中。 QTableWidgetItem的計數範圍在〜5000 - 10000之間。還有更多這樣的對象(#〜600 - 800)被構造,並且需要保留在內存中,直到有任何更改。
我在想,GC可能會減慢我的應用程序有時。因爲默認的GC閾值是700,10,10。就我而言,700似乎非常少。這些QTableWidgetItem保留在內存中,直到任何數據發生變化。那麼GC是否會在第一階段,第二階段和第三階段頻繁踢球? 一旦數據發生變化,我只需通過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)
編輯:在執行此循環時,進度對話框越來越慢。但是還有很多其他事情正在爲這些數據和更多Qt對象創建巨大的表格。另外,QGraphicsItem的圖表繪製變慢。目前, 我已經評論了qApp.processEvent()用於測試目的,在Qt的錯誤列表中表示QProgressDialog.setValue在內部調用processEvents,因此我不需要顯式調用。此外,還有一個凍結問題,應用程序在此進度對話框中凍結並需要將其殺死。
我用objgraph http://mg.pov.lt/objgraph/獲得內存 最頂端的50個對象這是我所得到的,當我打開應用程序首次
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
運行可能泄露的代碼後,最上面的內存中有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問題。你能告訴我們一些代碼嗎? – goertzenator