2011-03-01 69 views
0

应用程序详细信息: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等一样被创建并保存在内存中。当我创建新对象时,这些对象被新对象覆盖,从而使旧对象被取消引用。 测试内存泄漏的其他方法是什么?

+0

这味道更像泄漏比gc问题。你能告诉我们一些代码吗? – goertzenator

回答

0

你可以尝试关闭垃圾收集来测试你的理论:

gc.disable() 

或者更好的是:

gc.set_debug(gc.DEBUG_LEAK) 

the relevant page在Python参考更多。