应用程序详细信息: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