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 20:19:49 UTC
On Sat, Aug 02, 2003 at 04:11:58PM +0200, Enrico Colombini wrote:
> On Saturday 02 August 2003 15:30, Luca Giuzzi wrote:
> > 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.
> 
> Non mi pare, consdierato "Usually, all it can do is allow a
> later call to `malloc' to reuse the space". O non ho capito quello che 
> intendi?
> 
Ci sono essenzialmente due metodi per allocare memoria in modo dinamico
1) allocazione diretta delle pagine ... (alla fine fai una vmalloc a
 livello di kernel)
2) mmap anonimo (in cui tu mappi n bytes di /dev/zero in un range di
 indirizzi virtuali, richiedendo il Copy-On-Write).

Dal punto di vista dell'efficienza, chiaramente, vmalloc e' la soluzione
 migliore... c'e' un piccolo inconveniente, pero', che e' quello 
 della frammentazione della memoria (e anche quello che una vmalloc
 richiede che la memoria sia DISPONIBILE nel senso che la quantita'
 allocata deve essere <= RAM+SWAP... non si puo' fare overcommit in
 questo caso)
L'mmap anonimo ha altri vantaggi: 
 a) e' possibile fare dell'overcommit
 b) non da' luogo a frammentazione di memoria (l'area e' allocata e
 deallocata nel momento in cui viene fatta una free e il sistema e'
 libero di rimappare i buffers)
ma e' chiaramente piu' lento.

Come funziona la malloc della glibc?
 Essenzialmente segue questa strategia:
 se il blocco richiesto e' piccolo (il concetto di `piccolo' viene
 definito mediante mallopt), allora si utilizza vmalloc;
 se il blocco e' grande, allora il guadagno in tempo che uno ha
 nel fare l'allocazione diretta della memoria non compensa l'appesantimento
 del sistema dovuto alla mancanza di RAM, per conseguenza viene fatta una
 mmap.

 La differenza fra le due strategie, oltre che da uno strace, appare
 nel momento in cui si cerca di liberare memoria con free().

 La free() su di un blocco mmap-ato porta alla liberazione del blocco
 e ad una diminuzione della memoria occupata dal processo. 
 La free() su di un blocco vmalloc-ato invece NON porta (e questo e'
 il senso della nota) ad una restituzione di RAM al sistema: per le
 considerazioni di prima sulla frammentazione della RAM, questo
 e' piu' pernicioso che utile, per cui la glibc mantiene una cache
 delle aree precedentemente allocate e tenta di riutilizzarle per
 allocazioni successive.

Praticamente:
 a) free di una area di memoria grossa (mmap) -> restituisce la RAM al sistema
 b) free di una area di memoria `piccola' (vmalloc) -> rende l'area disponibile
    per eventuali successive malloc() all'interno del programma mettendola
    in una sorta di `cache locale'. Tutta la memoria, ovviamente, viene
    restituita al sistema quando il processo termina.

Ciao,
 lg

>   .Erix.

-- 



Maggiori informazioni sulla lista Lug