整理的参考文献,记不清了
1 背景简介
出现疑似”内存泄露”问题: malloc申请的内存,free释放以后没有归还操作系统,比如内存模块占用的内存为10GB,释放内存以后,通过TOP命令或者/proc/pid/status查看占用的内存有时仍然为10G,有时为5G,有时为3G, etc,内存释放的行为不确定。
2 malloc()/free(), mmap(), brk(), 用户程序-->glibc -->linux kernel之间的关系
1) malloc()/free() 是C语言中常用的两个内存 分配/释放 函数,但是ANSI C并没有指定它们具体应该如何实现。因此在各个系统级平台上(windows, mac, linux等等),函数的底层的内存操纵方式并不一样。
2) 在linux下,malloc()/free()的实现是由 glibc库 负责,它会根据一定的策略与系统底层通信(调用系统API),所以,用户程序并不会直接和linux kernel进行交互,而是交由glibc托管,提供默认的内存管理器。关系为:用户程序 ---->glibc---->linux kernel。
3) glibc使用了 ptmalloc 作为其内存管理器的实现。
* brk分配的内chunk list,只能从top开始线性向下释放。中间释放掉的chunk,无法归还给OS,而是链入到了bins/fast bins的容器中。
* mmap分配的内存,等于直接从物理内存中映射了一块过来,释放这块内存时,可以直接归还给OS。
* 对于request的一块内存,到底是由brk分配,还是由mmap分配,这是由glibc策略机制决定的。 有个threshold,可以调节这种策略,默认小于threshold由brk分配,大于等于则由mmap分配, threshold默认为128kb。glibc具体从那个版本开始支持动态调节threshold需要调查。默认下,在64位系统上,brk可以动态调整到从 128kb到32mb。调整策略基本可以概括为:发现对顶可以release的可用内存超过256kb的话,就将threshold调整到256kb,依次类推直到32mb.
glibc使用的两种用户程序内存管理机制,考虑了与系统底层通信代价,如果直接操纵大量小块内存,频繁地与系统调用进行通信,会降低程序的运行效率。将小块内存放入brk维护的堆中,等于实现了一 块缓存(cache),用完了可以先攒起来,到时候可以一起归还给系统。但是由于它的实现,只维护了堆顶的一个指针。因此想要内存归还系统,必须从顶向下,依次归还。在这种机制下,如果堆顶有块内存一直被占用,底下所有内存虽然都已经没用了,但是这种设计决定内存此时不可以还给系统,因此出现了“洞(Hole)”的问题。这种设计对一些由于业务需求,频繁申请/释放小块内存的用户程序而言,问题会比较突出。虽然glibc制定了这种有些“强硬”的内存管理方案,但是也提供了一些方法允许调节相关阈值(threshold),虽然不能干涉管理内存,但可以通过这些方法,决定“多大算大,多小算小”以及“攒到多少就归还”等这类问题。
3 mallopt() 与 malloc_trim(0)
1) mallopt是一个专门调节相关阈值的函数
URL: http://man7.org/linux/man-pages/man3/mallopt.3.html
#include < malloc.h > int mallopt(int param, int value); M_MMAP_THRESHOLD For allocations greater than or equal to the limit specified (in bytes) by M_MMAP_THRESHOLD that can't be satisfied from the free list, the memory-allocation functions employ mmap(2) instead of increasing the program break using sbrk(2). Allocating memory using mmap(2) has the significant advantage that the allocated memory blocks can always be independently released back to the system. (By contrast, the heap can be trimmed only if memory is freed at the top end.) On the other hand, there are some disadvantages to the use of mmap(2): deallocated sp

本文探讨了Linux系统中glibc如何管理内存,包括malloc/free、mmap、brk的关系,以及mallopt和malloc_trim的使用。glibc通过ptmalloc实现内存管理,存在brk分配内存导致的内存洞问题。通过mallopt可以调节内存分配策略,malloc_trim用于释放堆顶以上的内存。针对内存释放不彻底的问题,提出了解决方案,如调整M_MMAP_THRESHOLD等参数。
最低0.47元/天 解锁文章
1388

被折叠的 条评论
为什么被折叠?



