应用程序详细信息:pyQt应用程序,Qt 4.4和python 2.5
问题:随着时间的推移(使用应用程序很长时间没有关闭),应用程序有时会变慢。我尝试了大部分的分析应用程序,但没有找到任何重要的指出任何问题。
我的应用程序使用QTabWidget在不同的选项卡中创建多个表。因此,为了加快Tab切换,我只构造一次表并将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)
编辑:执行此循环时,进度对话框持续变慢和变慢。但是还有许多其他事情正在发生,例如为这些数据和更多Qt对象创建大表。此外,QGraphicsItem的图表绘图变得更慢。目前, 我已经评论了qApp.processEvent()用于测试目的,在Qt的bug列表中它说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等。当我创建新对象时,这些对象被新对象覆盖,从而使旧对象被取消引用。 测试内存泄漏的其他方法是什么?
答案 0 :(得分:0)
你可以尝试关闭垃圾收集来测试你的理论:
gc.disable()
或更好:
gc.set_debug(gc.DEBUG_LEAK)
有关详细信息,请参阅python参考中的the relevant page。