メモリの割り当てと解放が頻繁に行われる、長期間実行されるアプリケーションがあります。malloc
実装によって解放されたメモリがシステムに戻されるでしょうか?
この点に関して、次のような動作はどうでしょうか。
- ptmalloc 1、2(glibcのデフォルト)または3
- dlmalloc
- tcmalloc (Google スレッド malloc)
- Solaris 10-11 のデフォルトの malloc と mtmalloc
- FreeBSD 8 のデフォルトの malloc (jemalloc)
- malloc を蓄えますか?
アップデート
昼間と夜間でメモリ消費量が大きく異なるアプリケーションがある場合 (例)、 のいずれかでmalloc
解放されたメモリをシステムに強制的に返すことはできますか?
このような戻り値がなければ、解放されたメモリは何度もスワップアウトおよびスワップインされますが、そのようなメモリにはゴミしか含まれません。
ベストアンサー1
以下の分析は glibc にのみ適用されます (ptmalloc2
アルゴリズムに基づく)。解放されたメモリをシステムに戻すのに役立つと思われるオプションがいくつかあります。
マロプト()( で定義
malloc.h
) は、パラメータ オプションの 1 つを使用してトリムしきい値を設定するオプションを提供しますM_TRIM_THRESHOLD
。これは、データ セグメントの先頭で許可される空きメモリの最小量 (バイト単位) を示します。量がこのしきい値を下回ると、glibc は を呼び出してbrk()
カーネルにメモリを戻します。Linux ののデフォルト値は
M_TRIM_THRESHOLD
128K に設定されていますが、より小さい値を設定するとスペースを節約できる可能性があります。環境変数にトリムしきい値を設定することで
MALLOC_TRIM_THRESHOLD_
、ソースをまったく変更せずに同じ動作を実現できます。ただし、 を使用して実行された予備テスト プログラムで
M_TRIM_THRESHOLD
は、 によって割り当てられたメモリがmalloc
システムに返されるとしても、 によって最初に要求された実際のメモリ チャンク (領域) の残りの部分はbrk()
保持される傾向があることが示されています。malloc_trim(pad)
(で定義)を呼び出すことで、メモリ領域をトリミングし、未使用のメモリをシステムに戻すことができますmalloc.h
。この関数は、データ セグメントのサイズを変更し、その末尾に少なくともpad
バイトを残し、1 ページ分のバイト数未満しか解放できない場合は失敗します。セグメント サイズは常に 1 ページの倍数で、i386 では 4,096 バイトです。この変更された動作の実装は、malloc フック機能を使用して行うことができます。これにより、コア glibc ライブラリのソース コードを変更する必要はありません
free()
。malloc_trim
madvise()
のフリー実装内でシステム コールを使用しますglibc
。