What does "malloc_trim (0)" mean?

the man page told me this, and thanks to this I know a lot of knowledge about glibc memory management.

But I'm still confused. " malloc_trim (0) " (mark zero as a parameter) means (1.) Will all memory in the heap section be returned to the OS? Or (2.) only all the "unused" memory of the top of the heap area will be returned to the OS?

If the answer is (1.), what if memory is still used on the heap? if a bunch used momery in places somewhere, will they be eliminated or the function will not succeed?

If the answer is (2.), and what about the “ holes ” in the places, and not in the upper part of the heap, they are no longer used, but the upper part of the heap area is still used, will this call work effectively?

Thank.

+5
source share
2 answers

The man page for malloc_trimsays that it frees free memory, so if memory is allocated on the heap, it will not free the whole heap. There is a parameter if you know that you still need a certain amount of memory, so freeing more than this can cause glibc to do unnecessary work later.

, . , , - brk sbrk, , , , . , ; sbrk, , , .

, , (, mmap), , sbrk -.

+4

malloc_trim : https://github.com/mkerrisk/man-pages/blob/master/man3/malloc_trim.3, , , man-pages project supporter, kerrisk 2012 : https://github.com/mkerrisk/man-pages/commit/a15b0e60b297e29c825b7417582a33e6ca26bf65

grep glibc git, glibc man-, man- malloc_trim . glibc malloc : https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c malloc_trim malloc/malloc.c:

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 man-pages. 2012 , glibc. glibc M_TRIM_THRESHOLD 128 KB: 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 https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc ( glibc 2.9 ), mtrim ( , glibc man-):

  • malloc/malloc.c(public_mTRIm):

mTRIm . (mTRIm): madvise , .

( , ), , , MADV_DONTNEED <7 >

       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);
        }

madvise MADV_DONTNEED glibc : (shrink_heap), - (mtrim): 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);

malloc_trim C (test_malloc_trim.c) strace/ltrace:

#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

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

, malloc_trim(0) madvise MADV_DONTNEED 9 , 40008 .

0

All Articles