trang
Man of malloc_trim
đã cam kết ở đây: https://github.com/mkerrisk/man-pages/blob/master/man3/malloc_trim.3 và như tôi hiểu, nó đã được viết bởi người đàn ông-trang dự án duy trì, kerrisk vào năm 2012 từ đầu: https://github.com/mkerrisk/man-pages/commit/a15b0e60b297e29c825b7417582a33e6ca26bf65
Như tôi có thể grep the glibc's git, there are no man pages in the glibc, và không có cam kết manpage malloc_trim để ghi lại bản vá này. Các tài liệu tốt nhất và duy nhất của malloc glibc là mã nguồn của nó: https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c Có malloc_trim
ý kiến từ 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
Giải phóng từ giữa đoạn không ghi dưới dạng văn bản trong malloc/malloc.c và không được ghi lại trong dự án trang con người. Trang người dùng từ năm 2012 có thể là trang người đầu tiên của hàm, được viết không phải bởi tác giả của glibc. Trang thông tin của glibc chỉ đề cập đến M_TRIM_THRESHOLD là 128 KB: https://www.gnu.org/software/libc/manual/html_node/Malloc-Tunable-Parameters.html#Malloc-Tunable-Parameters và không liệt kê hàm malloc_trim https://www.gnu.org/software/libc/manual/html_node/Summary-of-Malloc.html#Summary-of-Malloc (và nó cũng không ghi nhớ memusage/memusagestat/libmemusage.so).
Vào tháng 12 năm 2007 đã có cam kết https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc bởi Ulrich Drepper (nó là một phần của glibc 2.9 và mới hơn) mà thay đổi mtrim
thực hiện (nhưng nó không thay đổi bất kỳ tài liệu hoặc trang người đàn ông như không có các trang người đàn ông trong glibc):
- malloc/malloc.c (public_mTRIm): Lặp lại khắp nơi đấu trường và gọi
mTRIm cho tất cả chúng. (mTRIm): Ngoài ra lặp qua tất cả các khối miễn phí và sử dụng madvise để giải phóng bộ nhớ cho tất cả các khối có chứa ít nhất một trang bộ nhớ .
phần chưa sử dụng của khối (bất cứ nơi nào, bao gồm cả khối ở giữa), xếp trên kích thước trang và có kích thước hơn trang có thể được đánh dấu là 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);
}
Đây là một trong tổng số hai tập quán của madvise
với MADV_DONTNEED
trong glibc bây giờ, một cho phần trên của đống (shrink_heap
) và khác được đánh dấu của bất kỳ đoạn (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);
Chúng tôi có thể kiểm tra malloc_trim
với chương trình này đơn giản C (test_malloc_trim.c
) và 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
Vì vậy, đã có madvise
với MADV_DONTNEED
cho 9 trang sau malloc_trim(0)
cuộc gọi, khi có lỗ 40008 byte ở giữa đống.
Hiện tại có phương pháp trả lại lỗ ở giữa vùng heap quay lại hệ điều hành: MADV_DONTNEED (và đôi khi là MADV_FREE): http://code.metager.de/source/xref/gnu/glibc/malloc/malloc.C# 4535 'mtrim (mstate av, size_t pad) ... __madvise (paligned_mem, kích thước & ~ psm1, MADV_DONTNEED);'. 'madvise' với những cờ như vậy đánh dấu các trang không cần thiết cho ứng dụng, hệ điều hành có thể phá hủy dữ liệu từ chúng và unmap không gian vật lý; truy cập tiếp theo vào trang có thể tạo ra pagefault để remap trang ảo vào không gian vật lý. – osgx
Mã đã được thêm vào https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc 68631c8eb92ff38d9da1ae34f6aa048539b199cc "(mTRIm): Ngoài ra lặp qua tất cả các khối miễn phí và sử dụng madvise để giải phóng bộ nhớ cho tất cả các khối có chứa ít nhất một trang bộ nhớ. " - \t Ulrich Drepper Ngày 16 tháng 12 năm 2007 (glibc 2.9) – osgx