OS にメモリを再利用させる唯一の確実でポータブルな方法は、プロセスを終了することです もう一度再起動すると、続行するために必要な状態が復元されます。
もちろん、必要に応じて brk/sbrk を使用して独自の malloc/free 実装を作成することも選択肢の 1 つです。
glibc malloc で malloc_trim
を呼び出してみてください 関数。十分に文書化されておらず、2007 年頃 (glibc 2.9) に変更がありました - https://stackoverflow.com/a/42281428.
2007 年以降、この関数は次のようになります:すべての malloc メモリ アリーナ (マルチスレッド アプリケーションで使用される) を繰り返し処理し、trim と fastbin の統合を行います。すべてのアラインされた (4KB) ページを完全に解放して解放します。
https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc
<ブロック引用>Ulrich DrepperSun, 16 Dec 2007 22:53:08 +0000 (22:53 +0000)
- malloc/malloc.c (public_mTRIm):すべてのアリーナを反復処理し、それらすべてに対して mTRIm を呼び出します。
(mTRIm):さらに、すべての空きブロックを繰り返し処理し、madviseto を使用して、少なくとも 1 つのメモリ ページを含むすべてのブロックに対してメモリを解放します。
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);
malloc_trim
を呼び出す 解放されたメモリのほとんどすべてを OS に解放します。まだ解放されていないデータを含むページのみが保持されます。 OS は、MADV_DONTNEED を使用して指示された場合、物理ページをマップ解除する場合とマップ解除しない場合があり、Linux は通常マップ解除します。適切なページは依然として VSIZE (プロセスの合計仮想メモリ サイズ) にカウントされますが、通常は RSS (プロセスが使用する物理メモリの量) を減らすのに役立ちます。
または、別の malloc ライブラリに切り替えることもできます:tcmalloc (gperftools / google-perftools) または jemalloc (facebook) のどちらにも、解放されたメモリを OS に戻す積極的なルールがあります (madvise MADV_DONTNEED または MADV_FREE を使用)。