Man Seite von malloc_trim
wurde hier begangen: https://github.com/mkerrisk/man-pages/blob/master/man3/malloc_trim.3 und wie ich sie verstehe, wurde es von Mann-Seiten Projekt Betreuers, Kerrisk im Jahr 2012 von Grund auf neu geschrieben: https://github.com/mkerrisk/man-pages/commit/a15b0e60b297e29c825b7417582a33e6ca26bf65
Wie kann ich grep the glibc's git, there are no man pages in the glibc, und nicht zu malloc_trim manpage begehen um diesen Patch zu dokumentieren. Die beste und die einzige Dokumentation von glibc malloc ist sein Quellcode: https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c Es gibt malloc_trim
Kommentare von 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
Befreit von der Mitte des Blockes nicht als Text in malloc dokumentiert/malloc.c und nicht im man-pages-Projekt dokumentiert. Man-Seite von 2012 kann die erste Manpage der Funktion sein, die nicht von den Autoren von glibc geschrieben wurde. Die Infoseite von glibc erwähnt nur M_TRIM_THRESHOLD von 128 KB: https://www.gnu.org/software/libc/manual/html_node/Malloc-Tunable-Parameters.html#Malloc-Tunable-Parameters und listet die malloc_trim Funktion https://www.gnu.org/software/libc/manual/html_node/Summary-of-Malloc.html#Summary-of-Malloc nicht auf (und dokumentiert auch nicht memusage/memusagestat/libmemuseage.so).
Im Dezember 2007 gab es commit https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc von Ulrich Drepper (es ist Teil von glibc 2.9 und höher), die mtrim
Implementierung geändert (aber keine Dokumentation oder man-Seite nicht, da es keine man-Seiten in glibc) sind ändern:
- malloc/malloc.c (public_mTRIm): iterieren alle Arenen und Anruf
mTRIm für alle von ihnen. (mTRIm): Zusätzlich über alle freien Blöcke iterieren und madvise verwenden, um Speicher für all jene Blöcke freizugeben, die mindestens eine Speicherseite enthalten.
Ungenutzte Teile Brocken (überall, einschließlich Stücke in der Mitte), ausgerichtet auf die Seitengröße und mit einer Größe mehr als Seite als MADV_DONTNEED
markiert werden können 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);
}
Dies ist eine von insgesamt zwei Verwendungen nun von madvise
mit MADV_DONTNEED
in glibc, ein für Oberteil von Halden (shrink_heap
) und anderer Kennzeichnung jeden Chunk (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);
Wir können die malloc_trim
mit diesem einfachen C-Programm testen (test_malloc_trim.c
) und 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
So gab es madvise
mit MADV_DONTNEED
für 9 Seiten nach malloc_trim(0)
Rufen Sie an, wenn in der Mitte des Heaps ein Loch von 40008 Bytes war.
Es gibt jetzt Methode zum Zurückbringen von Löchern in der Mitte des Heap zurück zum Betriebssystem: MADV_DONTNEED (und manchmal MADV_FREE): http://code.metager.de/source/xref/gnu/glibc/malloc/malloc.C# 4535 'mtrim (mstate av, size_t-Pad) ... __madvise (paligned_mem, Größe & ~ psm1, MADV_DONTNEED);'. 'madvise' mit solchen Flags markiert Seiten, die für die Anwendung nicht benötigt werden, das Betriebssystem kann Daten von ihnen zerstören und den physischen Speicherplatz aufheben; Der nächste Zugriff auf die Seite kann den Seitenfehler erzeugen, um die virtuelle Seite in den physischen Raum umzuordnen. – osgx
Code wurde hinzugefügt in https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc 68631c8eb92ff38d9da1ae34f6aa048539b199cc "(mTRIm): Zusätzlich iterieren über alle freien Blöcke und Verwende madvise, um Speicher für all jene Blöcke freizugeben, die mindestens eine Speicherseite enthalten. " - \t Ulrich Drepper 16.12.2007 (glibc 2.9) – osgx