人頁面在這裏承諾:https://github.com/mkerrisk/man-pages/blob/master/man3/malloc_trim.3,並按照我的理解,它是由人的頁面項目的維護者從頭寫起,kerrisk 2012年:https://github.com/mkerrisk/man-pages/commit/a15b0e60b297e29c825b7417582a33e6ca26bf65
,我可以grep the glibc's git, there are no man pages in the glibc,並沒有承諾malloc_trim手冊頁記錄這個補丁。的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並沒有記錄在man-pages項目中。 2012年的手冊頁可能是該函數的第一個手冊頁,不是由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月,由Ulrich Drepper提交了https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc(它是glibc 2的一部分)。9,並且改變mtrim
實施新)(不過那是glibc無人頁)它並沒有改變任何文件或手冊頁:
- 的malloc/malloc.c(public_mTRIm):遍歷所有競技場和電話
mTRIm所有這些。 (mTRIm):此外迭代所有空閒塊並使用madvise爲所有包含至少一個內存頁面的塊釋放內存。
塊的未使用的部分(任何地方,包括在中間塊),頁面大小對齊,並具有尺寸大於頁可被標記爲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);
}
這是總兩種用法之一的madvise
與glibc的MADV_DONTNEED
現在,一個用於(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);
我們可以用這個簡單的C程序(test_malloc_trim.c
)和strace
/ltrace
測試malloc_trim
:
#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
所以,有madvise
與MADV_DONTNEED
爲malloc_trim(0)
後9頁調用時,在堆的中間有40008個字節的空洞。
現在有一種將堆中間的孔返回到操作系統的方法: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,size&〜psm1,MADV_DONTNEED);'。帶有這種標誌的「madvise」標誌着應用程序不需要頁面,OS可能會銷燬它們的數據並取消映射物理空間;下一次訪問頁面可能會生成頁面錯誤以將虛擬頁面重新映射到物理空間。 – osgx 2017-02-16 11:48:45
代碼添加在https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc 68631c8eb92ff38d9da1ae34f6aa048539b199cc「(mTRIm):此外迭代所有空閒塊和使用madvise爲所有包含至少一個內存頁的塊釋放內存。「 - \t Ulrich Drepper 2007年12月16日(glibc 2.9) – osgx 2017-02-16 11:53:19