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
|