2010-08-24 14 views
5

Sto lavorando a un'app mobile Qt standard (scritta in C++, indirizzata ai dispositivi Symbian) e sto riscontrando che a volte quando l'app è chiusa (ad esempio tramite una chiamata a QApplication :: quit), il distruttore finale nell'app può richiedere molto tempo per tornare (30 secondi in più). Con questo voglio dire, tutte le operazioni di ripulitura nel distruttore sono state completate (rapidamente, tutto bene in un secondo) e abbiamo raggiunto il punto in cui l'esecuzione sta lasciando il distruttore e il codice che l'ha implicitamente chiamato (cioè quando cancelliamo l'oggetto).Distruttore Qt C++ che impiega molto tempo a restituire

Ovviamente a quel punto mi aspetto che l'esecuzione ritorni subito dopo la chiamata per eliminare l'oggetto, praticamente istantaneamente, ma come dico a volte questo sta prendendo un'età!

Questo lungo tempo di chiusura si verifica sia nelle versioni di debug che di release, con la registrazione abilitata o disabilitata, quindi non credo che questo sia un fattore. Quando raggiungiamo la fine del distruttore sono abbastanza sicuro che nessun handle di file sia rimasto aperto, o qualsiasi altra risorsa aperta (connessioni di rete, ecc.) ... sebbene anche se non dovessero presentarsi come un problema uscendo dal distruttore (?).

Si tratta dell'eliminazione dell'oggetto QMainWindow dell'applicazione. Attualmente la chiamata per farlo è in uno slot collegato a QApplication :: aboutToQuit, anche se ho provato a eliminare quell'oggetto anche nella funzione "main" delle app.

La durata del ritardo che abbiamo riscontrato sembra proporzionale alla quantità di attività nell'app prima di uscire. Questo mi fa pensare che le perdite di memoria possano essere un problema qui, ma non ne siamo a conoscenza (non significa che lo non sia ovviamente), e anche io non ho mai visto questo comportamento prima con trapelato memoria.

Qualcuno ha qualche idea su cosa potrebbe succedere qui?

Acclamazioni

+0

Si verifica questo problema se si utilizza anche un debugger? Riesci a isolare la/e riga/i di codice che impiega così tanto tempo? –

+0

Sì, lo vedo anche nel debugger. In termini di isolamento di quali segmenti di codice impiegano troppo tempo, il problema è che il ritardo si verifica mentre si torna dal distruttore stesso. Quindi l'ultima riga del distruttore ha terminato l'esecuzione, stiamo quindi uscendo dal distruttore ed è a questo punto che si verifica il ritardo. Credo che il framework Qt stia facendo qualcosa a quel punto che sta causando il ritardo, anche se non so ancora cosa. – busta83

risposta

4

Se il distruttore finale è per una classe di eredita QObject allora il distruttore QObject sarà chiamato subito dopo il distruttore del vostro oggetto finale. Presumibilmente questo oggetto è la radice di un albero di oggetti possibilmente grande che innesca un certo numero di azioni, incluso il richiamo del distruttore di tutti i QObjects secondari. Poiché dichiari che il problema è condizionato dalla quantità di attività, è probabile che un numero molto grande di bambini venga aggiunto all'albero degli oggetti che viene eliminato in questo momento, forse più di quanto previsto. Invece di aggiungere tutti gli oggetti a un albero gigante da eliminare tutto in una volta. Identifica gli oggetti che vengono creati spesso e che non hanno bisogno di persistere durante l'intera esecuzione. Invece di creare quegli oggetti con un genitore, avvia un nuovo albero che può essere cancellato prima (genitore = 0). Guarda QObject :: deleteLater() che attenderà fino a quando non ci sarà alcuna interazione da parte dell'utente per eliminare gli oggetti in questi alberi indipendenti.

+0

Ho iniziato a rimuovere alcuni dei genitoriali e ad usare deleteLater e sto vedendo miglioramenti notevoli nel tempo di distruzione. Roba eccellente, grazie! – busta83