
本文概述
内存管理是Linux内核的核心子系统,也是嵌入式Linux面试的进阶题。面试官想听的不是“malloc分配内存”,而是你懂不懂虚拟内存与物理内存的映射(页表、MMU)、内核态内存分配(kmalloc/vmalloc/伙伴系统)、以及嵌入式场景下的内存问题(内存泄漏、CMA、内存碎片)。本文从“进程看到的是虚拟地址”讲起,讲MMU与页表映射、用户态和内核态的内存分配接口、kmalloc(物理连续)与vmalloc(虚拟连续)的区别、以及嵌入式内存调试(free、泄漏检测、CMA),强调接口选择和内存问题定位依赖具体场景,不套固定值。
核心要点
Linux进程访问的是虚拟地址,由MMU+页表映射到物理内存,进程间隔离且可超配
用户态分配:malloc(堆、虚拟内存延迟分配),内核态分配接口不同
kmalloc:分配物理连续内存,适合驱动小对象;vmalloc:虚拟连续、物理可不连续,适合大块虚拟空间
伙伴系统+slab:内核底层内存管理,slab管理小对象
嵌入式关注:内存泄漏(用户态/内核态)、内存碎片、CMA(连续内存分配)
调试手段:free、cat /proc/meminfo、meminfo、kmemleak、valgrind
面试官考察点
考察点拆解
面试官问Linux内存管理,重点考察:第一,你懂不懂虚拟地址和物理地址的关系(MMU、页表、进程隔离);第二,你懂不懂内核态内存分配接口(kmalloc/vmalloc的区别和适用场景);第三,你懂不懂嵌入式内存问题(泄漏、碎片、CMA);第四,有没有实际排查过内存问题的经验。
追问方向:虚拟内存原理、kmalloc和vmalloc区别、内存泄漏怎么查、malloc和内核分配关系、为什么嵌入式要关心内存。
回答思路
答题主线
建议按“虚拟内存原理 → 分配接口 → 底层机制 → 嵌入式问题与调试”来答,先讲清机制再落到实践。
先讲原理:虚拟地址、MMU、页表。
讲分配接口:用户态vs内核态、kmalloc/vmalloc。
讲底层:伙伴系统、slab。
讲嵌入式:泄漏、碎片、CMA、调试。
参考回答
我先讲Linux内存管理的基本机制,再讲实际使用。
第一,虚拟内存原理。Linux进程访问的地址是虚拟地址,由MMU通过页表映射到物理内存。好处:进程间隔离(每个进程有独立地址空间)、可按需分配(虚拟内存可以大于物理内存,按需换入)、统一编程模型。嵌入式里虽然一般不用换页,但进程隔离和按需分配依然有效。
第二,分配接口。
用户态:malloc(glibc的堆分配,虚拟内存按需提交到物理页),free释放;
内核态:kmalloc分配物理连续的内存(适合驱动里小对象、DMA需要物理连续),vmalloc分配虚拟连续但物理可不连续的内存(适合大块、不需要物理连续的场景,代价是页表开销和性能略差);
驱动常用还有kzalloc(清零)、devm_kmalloc(和设备生命周期绑定)等。
第三,底层机制。内核底层用伙伴系统管理物理页(按2的幂次分配,解决大块分配),用slab分配器管理小对象(缓存常用结构,避免频繁分配释放)。kmalloc就是走slab/伙伴系统,vmalloc走独立的虚拟地址映射。
第四,嵌入式关注点。
内存泄漏:用户态泄漏(malloc不free)用valgrind/ASan查,内核态泄漏用kmemleak/检查alloc/free配对;
内存碎片:嵌入式长期运行后碎片化,分配大块连续内存失败,要注意分配策略和整理(CMA);
CMA(连续内存分配):为DMA/多媒体等需要大块物理连续的场景预留内存,平时可被回收,需要时分配;
监控:用 free、/proc/meminfo、/proc/buddyinfo 观察内存使用和碎片。
嵌入式内存有限,分配策略和泄漏排查是基本功。

扫码关注





























