内存分配器体系
Linux内存分配分为用户态与内核态两个层次。用户态应用程序通常通过libc提供的malloc()/free()管理堆内存;当空闲内存不足时,libc会通过brk()系统调用扩展堆大小,或通过mmap()创建新的匿名内存段。此外,tcmalloc、jemalloc以及JVM运行时等也提供独立分配器,它们可能绕过堆,直接使用mmap()映射私有段。内核自身的内存分配则依赖slab分配器,从系统空闲链表直接获取物理页。
内存页生命周期
一个典型用户内存页的生命周期包含以下步骤:
- 应用发起内存分配请求(如
malloc())。 - 分配库从空闲列表或通过
brk()/mmap()扩展虚拟内存。 - 应用首次访问该虚拟地址时,MMU触发缺页异常(page fault)。
- 内核从物理内存空闲列表中分配一页,建立虚拟到物理的映射,此时进程的常驻集大小(RSS)增加。
- 系统内存紧张时,内核页换出守护进程(kswapd)开始扫描LRU链表,寻找可释放的页:
- 未修改的文件缓存页直接释放;
- 脏页先写回磁盘再释放;
- 匿名页若存在swap设备则写入swap后释放。
- 若kswapd无法及时