2013-03-20 30 views
5

manual pageは私にそんなに教えてくれました。それを通して、私は "glibc"のメモリ管理に関する多くの背景知識を知っています。"malloc_trim(0)"とはどういう意味ですか?

しかし、私はまだ混乱します。 "malloc_trim(0)"(パラメータとしてゼロを書き留めます)の意味(1.) "ヒープ"セクションのすべてのメモリがOSに返されますか?または(2.)ヒープの最上位領域のすべての "未使用"メモリがOSに返されますか?

答えが(1.)の場合、まだ使用されているヒープ内のメモリは何ですか?ヒープがどこかの場所でモーメリを使用していた場合、それらは削除されるか、関数はうまく実行されませんでしたか?

答えがあるかの間(2.)、どのようなむしろヒープ内の上端よりの場所にあるもの「」について?彼らはもはや未使用のメモリだが、ヒープの一番上の領域がまだありますこの呼び出しは効率的に機能しますか?

ありがとうございました。

答えて

4

マニュアルページmalloc_trimには空きメモリが解放されているため、ヒープに割り当てられたメモリがある場合は、ヒープ全体が解放されません。あなたがまだ一定量のメモリを必要としていることを知っているなら、パラメータはそこにあります。それ以上の解放は、glibcが後で不必要な作業をしなければならなくなる原因になります。

ホールの場合、これはメモリー管理とメモリをOSに戻す際の標準的な問題です。プログラムで利用可能な主な低レベルヒープ管理はbrksbrkで、トップを変更してヒープ領域を拡張または縮小することができます。したがって、オペレーティングシステムにホールを返す方法はありません。プログラムがを呼び出すと、より多くのヒープを割り当てることができます。そのスペースは、空きスペースがある場合にのみ返され、返されます。

sbrkベースの割り当てとは異なる制約を持つ可能性のある、メモリを割り当てる他の複雑な方法(たとえば、匿名でmmap)があることに注意してください。

+0

ヒープの途中の穴を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

+0

コードが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

0

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_DONTNEEDhttps://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/ltracemalloc_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_trimstrace ./test_malloc_trim

を、 madvisemalloc_trim(0)後9ページの MADV_DONTNEEDでしたヒープの途中に40008バイトの穴があったときに呼び出します。

+0

GNUのようなプロジェクト管理者のマニュアルページやその他の文書の一般的な公式の位置:https://sourceware.org/bugzilla/show_bug.cgi?id=2531#c4 "Ulrich Drepper 2006-05-01マニュアルページはglibcで管理されていません。マニュアルページのメンテナにこれを伝えてください。 " – osgx

関連する問題