Satu-satunya cara yang andal dan portabel untuk mendapatkan kembali memori OS adalah dengan keluar dari proses dan mulai ulang lagi, pulihkan status apa pun yang Anda perlukan untuk melanjutkan.
Tentu saja, menulis implementasi malloc/free Anda sendiri menggunakan brk/sbrk sesuai kebutuhan Anda adalah opsi lainnya.
Dengan glibc malloc coba panggil malloc_trim
fungsi. Itu tidak didokumentasikan dengan baik dan ada perubahan di dalamnya sekitar tahun 2007 (glibc 2.9) - https://stackoverflow.com/a/42281428.
Sejak 2007 fungsi ini akan:Mengulangi semua arena memori malloc (digunakan dalam aplikasi multithreaded) melakukan konsolidasi trim dan fastbin; dan lepaskan semua halaman yang disejajarkan (4KB) dengan bebas sepenuhnya.
https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc
Ulrich DrepperSun, 16 Des 2007 22:53:08 +0000 (22:53 +0000)
- malloc/malloc.c (public_mTRIm):Iterasi semua arena dan panggil mTRIm untuk semuanya.
(mTRIm):Selain itu, ulangi semua blok kosong dan gunakan madviseto membebaskan memori untuk semua blok yang berisi setidaknya satu halaman memori.
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);
Jadi, panggil malloc_trim
akan melepaskan hampir semua memori yang dibebaskan kembali ke OS. Hanya halaman yang berisi data yang masih belum dibebaskan yang akan disimpan; OS mungkin unmap atau tidak unmap halaman fisik ketika madvised dengan MADV_DONTNEED dan linux biasanya melakukan unmap. halaman yang dibuat ulang masih dihitung hingga VSIZE (total ukuran memori virtual dari proses), tetapi biasanya membantu mengurangi RSS (jumlah memori fisik yang digunakan oleh proses).
Alternatifnya, Anda dapat mencoba beralih ke pustaka malloc alternatif:tcmalloc (gperftools / google-perftools) atau jemalloc (facebook), keduanya memiliki aturan agresif untuk mengembalikan memori yang dibebaskan kembali ke OS (dengan madvise MADV_DONTNEED atau bahkan MADV_FREE).