L'unico modo affidabile e portatile per fare in modo che il sistema operativo recuperi la memoria è uscire dal processo e riavvialo di nuovo, ripristinando qualsiasi stato necessario per continuare.
Ovviamente, scrivere la tua implementazione malloc/free usando brk/sbrk in base alle tue esigenze è l'altra opzione.
Con glibc malloc prova a chiamare malloc_trim
funzione. Non è ben documentato e ci sono state modifiche al suo interno intorno al 2007 (glibc 2.9) - https://stackoverflow.com/a/42281428.
Dal 2007 questa funzione:Itera su tutte le arene di memoria malloc (utilizzate nelle applicazioni multithread) eseguendo il consolidamento di trim e fastbin; e rilascia tutte le pagine allineate (4KB) completamente liberate.
https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc
Ulrich DrepperSun, 16 dic 2007 22:53:08 +0000 (22:53 +0000)
- malloc/malloc.c (public_mTRIm):itera su tutte le arene e chiama mTRIm per tutte.
(mTRIm):itera inoltre su tutti i blocchi liberi e usa madvise per liberare memoria per tutti quei blocchi che contengono almeno una pagina di memoria.
https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=malloc/malloc.c;h=c54c203cbf1f024e72493546221305b4fd5729b7;hp=1e716089a2b976d120c304ad75dd95c63737ad75;hb=68631c8eb92ff38d9da1ae34f6aa048539b199cc;hpb=52386be756e113f20502f181d780aecc38cbb66a
+ malloc_consolidate (av);
...
+ for (int i = 1; i < NBINS; ++i)
...
+ for (mchunkptr p = last (bin); p != bin; p = p->bk)
+ {
...
+ /* See whether the chunk contains at least one unused page. */
+ char *paligned_mem = (char *) (((uintptr_t) p
+ + sizeof (struct malloc_chunk)
+ + psm1) & ~psm1);
...
+ /* This is the size we could potentially free. */
+ size -= paligned_mem - (char *) p;
+
+ if (size > psm1)
+ {
...
+ madvise (paligned_mem, size & ~psm1, MADV_DONTNEED);
Quindi, chiamando malloc_trim
rilascerà quasi tutta la memoria liberata nel sistema operativo. Verranno mantenute solo le pagine contenenti dati non ancora liberati; Il sistema operativo può annullare o meno la mappatura della pagina fisica quando è madvised con MADV_DONTNEED e Linux di solito annulla la mappatura. le pagine madvised sono ancora conteggiate per VSIZE (dimensione totale della memoria virtuale del processo), ma di solito aiutano a ridurre RSS (quantità di memoria fisica utilizzata dal processo).
In alternativa, puoi provare a passare alla libreria malloc alternativa:tcmalloc (gperftools / google-perftools) o jemalloc (facebook), entrambi hanno regole aggressive per restituire la memoria liberata al sistema operativo (con madvise MADV_DONTNEED o anche MADV_FREE).