malloc_trim
のマンページがここにコミットされた:https://github.com/mkerrisk/man-pages/blob/master/man3/malloc_trim.3と私は理解して、それが人間 - ページのプロジェクトのメンテナによって書かれた、最初から2012年にkerrisk:https://github.com/mkerrisk/man-pages/commit/a15b0e60b297e29c825b7417582a33e6ca26bf65
私はgrep the glibc's git, there are no man pages in the glibcができ、無malloc_trim manページにコミットするようこのパッチを文書化する。最高とglibcのmalloc関数の唯一の文書は、そのソースコードです:https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c malloc/malloc.c
からmalloc_trim
コメントがあります。
Additional functions:
malloc_trim(size_t pad);
609 /*
610 malloc_trim(size_t pad);
611
612 If possible, gives memory back to the system (via negative
613 arguments to sbrk) if there is unused memory at the `high' end of
614 the malloc pool. You can call this after freeing large blocks of
615 memory to potentially reduce the system-level memory requirements
616 of a program. However, it cannot guarantee to reduce memory. Under
617 some allocation patterns, some large free blocks of memory will be
618 locked between two used chunks, so they cannot be given back to
619 the system.
620
621 The `pad' argument to malloc_trim represents the amount of free
622 trailing space to leave untrimmed. If this argument is zero,
623 only the minimum amount of memory to maintain internal data
624 structures will be left (one page or less). Non-zero arguments
625 can be supplied to maintain enough trailing space to service
626 future expected allocations without having to re-obtain memory
627 from the system.
628
629 Malloc_trim returns 1 if it actually released any memory, else 0.
630 On systems that do not support "negative sbrks", it will always
631 return 0.
632 */
633 int __malloc_trim(size_t);
634
はチャンクの途中からの解放は、malloc関数/ malloc.cにテキストとしてを文書化されていませんマニュアルページプロジェクトには記載されていません。 2012年のmanページはglibcの作者ではなく、関数の最初のマニュアルページです。 glibcの情報ページには128 KBのM_TRIM_THRESHOLDしか書かれていません: https://www.gnu.org/software/libc/manual/html_node/Malloc-Tunable-Parameters.html#Malloc-Tunable-Parametersとmalloc_trim関数https://www.gnu.org/software/libc/manual/html_node/Summary-of-Malloc.html#Summary-of-Malloc(memusage/memusagestat/libmemusage.soも記載されていません)のリストは表示されません。
2007年12月、ウルリッヒ・ドリッパー(glibc 2の一部です)がhttps://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199ccをコミットしました。
- のmalloc/malloc.c(public_mTRIm):以上のすべての反復処理
mtrim
実装を(glibcのにはmanページが存在しないとしてではなく、それは任意のマニュアルまたはmanページを変更していない)に変更9以降)アリーナとコール
mTRIm (mTRIm):さらに、すべての空きブロックを繰り返し、madvise を使用して少なくとも1つの メモリページを含むすべてのブロックのメモリを解放します。これは、合計2つの用途の一つであるページサイズに整列され、ページがMADV_DONTNEED
https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=malloc/malloc.c;h=c54c203cbf1f024e72493546221305b4fd5729b7;hp=1e716089a2b976d120c304ad75dd95c63737ad75;hb=68631c8eb92ff38d9da1ae34f6aa048539b199cc;hpb=52386be756e113f20502f181d780aecc38cbb66a
INTERNAL_SIZE_T size = chunksize (p);
if (size > psm1 + sizeof (struct malloc_chunk))
{
/* See whether the chunk contains at least one unused page. */
char *paligned_mem = (char *) (((uintptr_t) p
+ sizeof (struct malloc_chunk)
+ psm1) & ~psm1);
assert ((char *) chunk2mem (p) + 4 * SIZE_SZ <= paligned_mem);
assert ((char *) p + size > paligned_mem);
/* This is the size we could potentially free. */
size -= paligned_mem - (char *) p;
if (size > psm1)
madvise (paligned_mem, size & ~psm1, MADV_DONTNEED);
}
としてマークすることができるよりも多くのサイズを有する(真ん中のチャンクを含むどこでも)チャンクの
未使用部分http://code.metager.de/source/search?q=MADV_DONTNEED&path=%2Fgnu%2Fglibc%2Fmalloc%2F&project=gnu
H A D arena.c 643 __madvise ((char *) h + new_size, diff, MADV_DONTNEED);
H A D malloc.c 4535 __madvise (paligned_mem, size & ~psm1, MADV_DONTNEED);
:トップヒープの一部(
shrink_heap
)とのために今のglibcで
MADV_DONTNEED
、一つと
madvise
他の任意のチャンク(
mtrim
)のマーキングされています
私たちは、この単純なCプログラム(test_malloc_trim.c
)とstrace
/ltrace
でmalloc_trim
をテストすることができます:だから
write(1, "Test started\n", 13Test started
) = 13
brk(0) = 0xcca000
brk(0xcef000) = 0xcef000
write(1, "1:0xcca010 2:0xccee40 3:0xcd8a90"..., 441:0xcca010 2:0xccee40 3:0xcd8a90 4:0xcec320
) = 44
madvise(0xccf000, 36864, MADV_DONTNEED) = 0
...
nanosleep({1, 0}, 0x7ffffafbfff0) = 0
brk(0xceb000) = 0xceb000
、
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
int main()
{
int *m1,*m2,*m3,*m4;
printf("%s\n","Test started");
m1=(int*)malloc(20000);
m2=(int*)malloc(40000);
m3=(int*)malloc(80000);
m4=(int*)malloc(10000);
// check that all arrays are allocated on the heap and not with mmap
printf("1:%p 2:%p 3:%p 4:%p\n", m1, m2, m3, m4);
// free 40000 bytes in the middle
free(m2);
// call trim (same result with 2000 or 2000000 argument)
malloc_trim(0);
// call some syscall to find this point in the strace output
sleep(1);
free(m1);
free(m3);
free(m4);
// malloc_stats(); malloc_info(0, stdout);
return 0;
}
gcc test_malloc_trim.c -o test_malloc_trim
strace ./test_malloc_trim
を、
madvise
は
malloc_trim(0)
後9ページの
MADV_DONTNEED
でしたヒープの途中に40008バイトの穴があったときに呼び出します。
ヒープの途中の穴をOS:MADV_DONTNEED(時にはMADV_FREE)に戻す方法があります:http://code.metager.de/source/xref/gnu/glibc/malloc/malloc.c #4535 'mtrim(mstate av、size_t pad)... __madvise(paligned_mem、サイズ&〜psm1、MADV_DONTNEED);'。そのようなフラグを持つ 'madvise'はアプリケーションに必要のないページをマークし、OSはそれらのデータを破棄して物理空間をマップ解除することができます。ページへの次のアクセスは仮想ページを物理空間に再マッピングするためのページフォールトを生成することができる。 – osgx
コードがhttps://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc 68631c8eb92ff38d9da1ae34f6aa048539b199cc "に追加されました。(mTRIm):さらに、すべてのフリーブロックとmadviseを使用して、少なくとも1つのメモリページを含むすべてのブロックのメモリを解放してください。 - \t Ulrich Drepper 2007年12月16日(glibc 2.9) – osgx