2011-03-01 119 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參考更多。