Newsgroup: it.comp.os.linux.development
Titolo: GtkWidget con memory leak ??

Giocherellando un po' con le gtk ho trovato un problema strano,
( o magari sono io che non lo capisco :), dunque richiamando
un funzione con un timer periodico ( ma anche un ciclo for
andava bene lo stesso ) ho inserito in questo ciclo la creazione
di un widget qualsiasi ( Es. gtk_button_new() ) dopodiche ho
provveduto alla sua distruzione ( gtk_widget_destroy() ), la cosa
che non capisco e che se traccio il tutto con memprof, ho la
memoria in continuo aumento ogni qualvolta che eseguo il ciclo
come se la destroy non deallocasse lo spazio allocato in memoria
del widget, l'unico motivo che mi viene in mente e che magari
le gtk usino un sistema interno di cache per riutilizzare
la memoria in seguito, ho provato un po' di tutto anche
referenziando e deferenziando ( si scrive cosi? ) il widget,
le gtk usate sono quelle di defaul sulla RH7.3, il linguaggio
e il c, se qualcuno a qualche idea su questo problema
mi dia ( alla fantozzi ) una mano che ne sto uscendo pazzo....:(
ciao giuliano.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 provveduto alla sua distruzione ( gtk_widget_destroy() ), la cosa
Innanzitutto, che versione delle GTK stai usando? Le 2.0 sono ancora un
filino giovani, quindi hanno qualche leak in posti strani. Le 1.2 sono
molto più stabili, ed i leak dovrebbero essere stati tutti rimossi.
Secondo: i widget vengono distrutti quando il loro refcount scende a
zero. Se il ciclo termina troppo presto, c'è il rischio che il refcount
non ci arrivi mai, a zero. A questo punto, devi "forzare la mano",
e usare gtk_widget_unref(), che decrementa il refcount, e chiama
automaticamente gtk_widget_destroy() se il refcount è arrivato a zero.
Ciao,
 Emmanuele.
-- 
Emmanuele Bassi (Zefram)           [ 
http://www.radiance.d2g.com/~zefram
 ]
GnuPG Key fingerprint = 4DD0 C90D 4070 F071 5738  08BD 8ECC DB8F A432 0FF4

 
La funzione di prova che chiamo e circa cosi :
void FuncQualcosa(void) {
 
	lab30=gtk_button_new();	gtk_widget_ref(lab30); 
	gtk_object_set_data_full(GTK_OBJECT(lab30),lab30,lab30,(GtkDestroyNotify)gtk_widget_unref);
	gtk_widget_unref(lab30);
	gtk_widget_destroy(lab30);
}
Il widget lab30 e dichiarato esternamente in un modulo principale, tieni
conto che ho fatto diverse combinazioni di prove con unref e destroy, ma
memprof a ogni ciclo di funzione continua a segnare l'aumentare di
memoria usata che comunque viene indicata anche con il comando "top"..
Ciao e grazie.

 }
In pratica nel gtk_object_set_data_full passavo come primo oggetto lo
stesso widget invece che quello di riferimento ( la finestra principale )
ora e tutto a posto chiedo venia per l'errore......:))

memoria usata che comunque viene indicata anche con il comando "top"..
Fregatene.
Le glib 1.2 utilizzano un sistema che ricicla la memoria che viene
allocata con g_malloc e poi deallocata con g_free. Quindi, anche se tu
deallochi la memoria, il sistema sottostante non lo fa. Questo per
ragioni di efficienza: l'allocazione di memoria e' molto onerosa, e le
gtk di solito ne fanno molto uso (come ogni programma di un certo
livello...), quindi cercano di minimizzare l'impatto creando un pool
di memoria gia' allocata e comunque poi dichiarata dal programmatore
come libera.
E' per questo che vedi che la memoria non decresce... Puoi ricompilare
le glib con un flag che disabilita questa gestione.
Nota: le glib 2.0 invece fanno il contrario. Di default non abilitano
i pool di memoria
-- 
+---- | Un OS per domarli, Un OS per trovarli,             |  -o)
+---+ | Un OS per ghermirli e nel buio incatenarli         |  /\\
 O  | | Nella terra di Redmond, ove l'ombra cupa scende... | _\_V
                    raffaele punto salmaso presso libero punto it

 memoria usata che comunque viene indicata anche con il comando "top"..
Fregatene di top, dato che non funziona bene con le GTK. ;-)
Come ho detto, le GTK tengono conto internamente di quali e quanti
widget debbono essere eliminati dalla memoria. Quello che ti sembra
un leak, è solo un ritardo nella deallocazione.
Prova ad usare un timer con una latenza di un secondo o più, e vedrai
che i leak spariscono. A quel punto, potrai "fregartene"... ;-))
Altrimenti, prova a scaricare i sorgenti, giusto per eliminare
eventuali rimaneggiamenti della red hat (cosa di cui dubito, però).
Ti darei anche un pointer verso le FAQ, ma, purtroppo, la sezione è down
al momento (a quanto ho potuto vedere alle 02.00 del mattino). Lì dentro
c'è, comunque, una risposta esattamente alla tua domanda.
+++
Parlo per esperienza personale: ho visto programmi con le GTK
sperimentali (1.3) che perdevano anche 200K ad ogni ciclo. Con le 1.2,
invece, non ho problemi neppure con il binding per il Perl (ho un
programma in Perl/GTK che si ciuccia 8 mega di memoria, ma non perde
neanche un byte, se non quando non faccio qualche idiozia).
