[Python] weakref ... troppo deboli!...

Alessandro Dentella sandro a e-den.it
Ven 28 Maggio 2010 17:13:57 CEST


On Fri, May 28, 2010 at 03:49:35PM +0200, Marco Giusti wrote:
> On Fri, May 28, 2010 at 01:39:43PM +0200, Alessandro Dentella wrote:
> > Grazie Marco per la dritta, 
> > 
> > On Fri, May 28, 2010 at 12:19:12PM +0200, Marco Giusti wrote:
> > > On Fri, May 28, 2010 at 10:25:51AM +0200, Alessandro Dentella wrote:
> [...]
> > > 
> > > Vediamo un po' tutti i possibili problemi che possono sorgere:
> > > 
> > > 1. il metodo `delete_event_cb` elimina il riferimento alla finestra ma
> > > il metodo può essere ancora chiamato dal padre e non essendoci più
> > > riferimenti a `self.w`...
> > 
> > non mi è chiaro, il padre sarebbe l'istanza stessa? Eliminata 'w', che
> > tramite le callback aveva riferimenti (forti, direi) a 'g', g dovrebbe
> > sparire per me...
> > 
> > Vedo che la grossa differenza fra la mia e la tua versione è nel fatto che io
> > ho una connect a 'delete_event' che tu non hai, entrambe però eliminiamo con
> > una chiamata diretta a destroy() la finestra, che quindi emette un
> > 'delete_event'. Quindi io passo due volte dal metodo 'delete_event_cb', la
> > seconda volta il metodo non ha più self.w... ho capito!
> 
> quell'esempio è solo una diversa implementazione del tuo esempio, se
> devi fare una comparazione con il tuo, controlla l'altro. nel secondo
> esempio l'unica differenza è l'attributo `self.objects` che contiene i
> riferimenti forti agli oggetti.

Mi ero reso conto che lasciando riferimenti forti non verificavo alcun
problema. Vedi le righe commentate nel primo esempio che ho postato, che lo
rendono di fatto identico al tuo ultimo.

> > Probabimente la dipendenza dal numero di finestre create è poi dovuta a
> > ritardi di gtk che è alle prese con il rendering delle finestre. La 10.04
> > era simulata in VirtualBox quindi più lenta e quindi mi dava l'errore già a
> > 3/4 finestre.
> 
> credo che questo sia un effetto aleatorio, che dipende da quando il gc
> entra in funzione, dal SO, dalla quantità di ram, ecc.
> 
> > > 2. gli unici riferimenti che hai agli oggetti `G` sono dei riferimenti
> > > deboli. a questo punto credo che tu debba andare a vedere come i
> > > riferimenti deboli siano implementati in pygtk. non sono molto preparato
> > > qui ma sicuramente il problema è questo. Accanto a `self.windows`
> > > affianca un'altra lista: `self.objects` con riferimenti forti, vedrai
> > > che a questo punti non hai più di questi problemi.
> > > 
> > > per quanto ne so' la gestione dei riferimenti in pygtk è pensata per, ad
> > > eccezione di casi particolari, potersene dimenticare. nel momento in cui
> > > non ci sono più riferimenti python ad un oggetto gobject, questo viene
> > > deallocato.
> > 
> > Il tutto è nato proprio perché vedo crescere a dismisura l'occupazione di
> > ram in una applicazione GTK e sto pensando di rimpiazzare riferimenti forti
> > con riferimenti deboli. Questo test era nato proprio dall'esigenza di
> > vedere se riuscivo a tenere la RAM sotto controllo.
> > 
> > promesso che apro altre discussioni per la ram...
> 
> secondo me non è il modo migliore per procedere, a meno che tu non sia
> certo che il memory leak dipenda proprio dalle gtk e non da un bug nel
> tuo programma.

In verità io sono ancora nella fase in cui sto cercando di capire dove sta
il bug convinto al moento che stia nel mio modo di procedere. Come hai
seggerito nell'altra mail pygtk dovrebbe non dare problemi ed io non mi son
posto problemi fino ad oggi.

Creo delle finestre di editing di dati SQL che sono delle classi che hanno
molte cose all'interno:

  class SqlMask(...):
     una stringa per il layout (xml o altro)
     la sessione sqlalchemy
     una query
     una lista di tabelle
     una lista di filtri e una di completion (filtri e completion miei che a
         loro volta hanno svariati oggetti gtk annessi)
     una lista di record
     una lista di SqlTable in relazione (es quelle che mostrano relazioni
         one2many, etc)
     ...

Molti di questi oggetti (filtri, completion in particolare) hanno
riferimenti all'oggetto SqlMask per cui vivono (o in cui vivono), il che
tiene in vita l'oggetto fino a che non vengano completamente eliminati.

Quando l'utente chiude la finestra io mi occupavo solo di distruggere la
finestra principale lasciando quindi un mondo di oggetti che si tenevano
reciprocamente in vita, per *studiare* questi ho usato le weakref,
ovvero per vedere se gli oggetti stanno sopravvivendo o meno alla chiusura
della finestra ed in caso capire chi le tiene in vita.

Non mi è chiaro, ed accetto volentieri suggerimenti su quale sia una buona
pratica per fare piazza pulita di tutti gli attributi: esiste una cosa
analoga a 'del dir[:]' per gli attributi? Altre precauzioni?

grazie ancora
sandro
*:-)


-- 
Sandro Dentella  *:-)
http://sqlkit.argolinux.org        SQLkit home page - PyGTK/python/sqlalchemy


Maggiori informazioni sulla lista Python