linux user group brescia

immagine del castello

Archivio della mailing list

Cattiva free() e OpenOffice

Luca Giuzzi giuzzi a lugbs.linux.it
Sab 2 Ago 2003 13:30:00 UTC
On Fri, Aug 01, 2003 at 08:58:57PM +0200, Vernia Damiano wrote:
> 
> 	Rispondo a tutti qui perche' siete stati cosi' gentili da 
> rispondermi in tantissimi :-))
> 
> >>> giustificare la grande quantita' di RAM usata. Credete che allocare e 
> >>> deallocare sempre e solo blocchi delle medesime dimensioni possa 
> >>> migliorare questo aspetto?
> >> Non penso, acnhe se non ho mai fatto esperimenti specifici.
> >> L'operazione di free e' piuttosto costosa in termini di risorse...
> > Non so se me lo sono sognato adesso o se l'ho letto da qualche parte. Puo'
> > darsi che tutte le free vengano rimandate sino a quando la memoria non e'
> > piena.
> 
> 	Io non ho idea di quale caso sia avvenuto, so solo che col mio 
> programma arrivavo ad occupare anche piu' di 100MB di ram nonostante 
> facessi tutte le free() per bene. Di questo ne sono sicuro. Ammetto di non 
> aver indagato piu' a lungo la questione di mmap e dei chunk di memoria 
> visti da glibc (premessa: lavoro con RH7.1/RH7.3 su PC AMD/Intel), ma 
> pensavo che il problema fosse del tipo indicato da Giuzzi con l'esempio 
> delle malloc().
> 
BTW: aggiungo una cosa che ho visto or ora nelle pagine della glibc
(nascosta, obiettivamente):

   Occasionally, `free' can actually return memory to the operating
system and make the process smaller.  Usually, all it can do is allow a
later call to `malloc' to reuse the space.  In the meantime, the space
remains in your program as part of a free-list used internally by
`malloc'.

Da questa nota (che NON si applica quando tu forzi l'impiego di mmap
nel modo in cui si diceva prima) si evince che il recupero della memoria
in seguito ad una free e' una evenienza piuttosto inusuale (e dovuta
al fallback su mmap per allocazioni "grosse")...
credo che questo possa rispondere alla domanda una volta per tutte,
indipendentemente dalla frammentazione di memoria.
> 
> >> Opterei per una sorta di meccanismo di caching che evita di effettuare free
> >> finche' e' possibile.
> 
> 	Ho fatto qualcosa di simile allocando all'inizio del programma 
> tutte le strutture temporanee che servono anche nei suoi moduli (e di cui 
> al compile-time non conosco la dimensione, e' ESCLUSIVAMENTE per questo 
> che sono costretto ad usare malloc()). In questo modo ho ridotto 
> drasticamente il numero di malloc()/calloc() e free() nel funzionamento 
> "vero" del programma.
> 
Questa e' una buona cosa comunque in quanto riduce l'overhead nel momento
in cui effettivamente devi fare i calcoli.


> 
> > AFAIK si puo' usare la glib che ha appunto un meccanismo interno di caching
> > di malloc e free.
> 
> 	Puo' darsi, non so. Comunque alla fine della fiera ho impiegato 
> una giornata e ho modificato leggermente le strutture dati e i moduli di 
> piu' basso livello del mio programma. malloc() e free() ora sono molte 
> meno (anche se ho dovuto sostituirle con alcune memcpy()) e soprattutto, 
> dati i parametri nell'istanza del problema da analizzare, sono di 
> dimensioni fisse e fatti dopo l'allocazione di tutte le altre strutture di 
> diversa dimensione.
> 	Risultato: da qualche decina/centinaia di MB di ram utilizzati (e 
> costantemente in _lenta_ ma inesorabile crescita) sono passato a 600/700 
> KILO byte, dimensione ragionevole stimando la dimensione dell'istanza del 
> problema.

Beh... penso che questo sia un guadagno sia in termini di funzionalita'
sia in termini di snellezza del codice ... non sarei sorpreso se ci fossero
stati pure miglioramenti prestazionali (di ordine minimo, in quanto
il vecchio collo di bottiglia era presumibilmente la RAM, pero' dovrebbero
esserci)

> 	Spiegazione che mi do: E' vero tutto quanto e' stato detto, a 
> partire dai pezzi non riutilizzati da malloc() come suggerisce Giuzzi 
> fino al caching della memoria utilizzata come ha detto Cowo. Ammetto che 
> puo' essermi sfuggito qualche free(), anche se immagino di entita' tanto 
> piccola (si parla di qualche - < 10 - unsigned a volta) da non 
> giustificare crescite cosi' enormi di memoria.
> 
BTW: se vuoi testare il tuo programma `in condizioni di laboratorio'
(per trovare memoria allocata e non liberata, ma anche per verificare
l'impatto del codice sulla cache, etc. etc.) ti consiglio di provare
valgrind... e' veramente ben fatto 


Ciao,
 lg



Maggiori informazioni sulla lista Lug