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

Marco Giusti marco.giusti a gmail.com
Ven 28 Maggio 2010 15:49:35 CEST


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.

> 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.

weakref diventa molto utile quando devi conservare in memoria dati
binari di dimenzioni considerevoli come un'immagine. in quel caso ha
senso usare i riferimenti deboli: se il SO richiede di liberare la
memoria il riferimento viene perso ma lo si può comunque andare a
recuperare i dati. es:

	class Img(object):

		_img = None
		@property
		def img(self):
			if self._img is None:
				self._img = open(self.filename).read()
			return self._img

		def __init__(self, filename):
			self.filename = filename

> > ps. ti allego la versione modificata.
> > 
> > pps. la gerarchia che crei è con soli due livelli, perché allora non usi
> > due classi distinte? ti allego la versione modificata
> 
> Perché nell'esempio reale alcune istanze della classe Mask gemmano altre
> istanze della classe Mask, poi nell'esempio ho cambiato il look solo perché
> non fosse troppo fuorviante vedere interfacce uguali.

ti allego un altro esempio che forse ti spiegherà meglio. lancialo due
volte, la prima così come è, la seconda volta commenta tutti i
riferimenti a `self.objects` che ti ho segnato. usando le callback puoi
vedere quando gli oggetti sono deallocati.

infatti quando tu hai l'eccezione:

	AttributeError: 'G' object has no attribute 'title'

puoi notare come gli attributi dell'oggetto siano stati tutti liberati.

ciao
m.

-- 
C'è un'ape che se posa
su un bottone di rosa:
lo succhia e se ne va...
Tutto sommato, la felicità
è una piccola cosa.
	
		-- Trilussa, Felicità
-------------- parte successiva --------------
Un allegato non testuale è stato rimosso....
Nome:        testd2_win.py
Tipo:        text/x-python
Dimensione:  1901 bytes
Descrizione: non disponibile
Url:         http://lists.python.it/pipermail/python/attachments/20100528/8382ed38/attachment.py 


Maggiori informazioni sulla lista Python