1.ptmalloc2 源码剖析3 -- 源码剖析
2.Linux内存管理(三)--内存分配之malloc
ptmalloc2 源码剖析3 -- 源码剖析
文章内容包含平台配置、源码malloc_state、分析arena实例、源码new_arena、分析arena_get、源码arena_get2、分析laya游戏源码heap、源码new_heap、分析grow_heap、源码heap_trim、分析init、源码malloc_hook、分析00H源码malloc_hook_ini、源码ptmalloc_init、分析malloc_consolidate、源码public_mALLOc、sYSMALLOc、freepublic_fREe、systrim等关键模块。
平台配置为 Debian AMD,使用ptmalloc2作为内存分配机制。
malloc_state 表征一个arena,全局只有一个main_arena实例,活码云源码arena实例通过malloc_init_state()函数初始化。
当线程尝试获取arena失败时,通过new_heap获取内存区域,构建非main_arena实例。
arena_get和arena_get2分别尝试线程的私有实例和全局arena链表获取arena,若获取失败,则创建new_arena。
heap表示mmap映射连续内存区域,每个arena至少包含一个heap,且起始地址为HEAP_MAX_SIZE整数倍。
new_heap尝试mmap映射内存,云好客源码实现内存对齐,确保起始地址满足要求。
grow_heap用于内存扩展与收缩,依据当前heap状态调用mprotect或mmap进行操作。
heap_trim释放heap,条件为当前heap无已分配chunk或可用空间不足。
init阶段,通过malloc_hook、realloc_hook和__memalign_hook函数进行内存分配。
malloc_consolidate合并fastbins和unsortedbin,优化内存分配。社区拼团源码
public_mALLOc作为内存分配入口。
sYSMALLOc尝试系统申请内存,实现内存分配。
freepublic_fREe用于释放内存,针对map映射内存调用munmap,其他情况归还给对应arena。
systrim使用sbrk归还内存。
Linux内存管理(三)--内存分配之malloc
本文将探讨 Linux 中动态内存分配的核心机制,特别是 malloc 函数的运作原理。开源社区提供了丰富的内存分配器,其中 glibc 中的 ptmalloc2 就是基于 dlmalloc 并引入多线程支持的实例。malloc 的源码位于 glibc-2.\malloc\malloc.c 文件中,它实际上是指向内部实现的别名 __libc_malloc。
动态内存分配主要通过两个系统调用完成:mmap 和 brk。当所需内存大小超过预设阈值(默认KB)时,使用mmap分配;否则,采用brk分配。这一策略旨在平衡系统调用的频繁程度与内存分配的效率。
为了提升效率,malloc 实际上利用了池化思想,预先分配较大的内存块,以便在后续请求时直接使用,避免频繁调用系统调用。这一过程涉及多个核心数据结构的使用,包括 arena、malloc_state、heap_info、chunk 等。
arena 被用来表示连续的堆区域,分为 main arena 和 thread arena。main arena 作为全局变量存在于 libc.so 的数据段中,不需维护多个堆,且可通过 sbrk 扩展堆段。在内存耗尽时,main arena 可以通过 sbrk 或 mmap 扩展堆段至遇到内存映射段。另一方面,thread arena 的数量有限,以减少开销,当线程数量超过 arena 数量时,arena 开始共享。
heap_info 用于存储堆的元数据,当一个 thread arena 的堆空间耗尽时,新的堆会映射到该 thread arena 中。chunk 则是描述内存分配的基本单位,包含 chunk 的大小、上一个 chunk 的状态信息以及对齐需求。
在内存组织方面,存在多种类型的 chunk,包括已分配 chunk、空闲 chunk、top chunk 和 last remainder chunk。top chunk 位于 arena 的最顶部,用于处理所有 bin 中未找到合适空闲内存的情况。当 top chunk 大小不合适时,它会被分割或通过系统调用扩容。
关于 free chunk 的管理、brk 与 mmap 的详细解释将在后续文章中深入探讨。更多关于内存管理的内容可参考《嵌入式 Linux 笔记》专栏。请在引用时注明出处。