深入解析 kmalloc、vmalloc 和 malloc

目录

1. malloc(用户态内存分配)

2. kmalloc(内核态物理连续内存分配)

3. vmalloc(内核态虚拟连续内存分配)

4. 总结对比表

5. 小Tips


在内核开发、驱动编写,甚至日常应用开发中,我们经常会遇到三种不同的内存分配接口:mallockmallocvmalloc。它们虽然名字相似,但应用场景和内部实现却有很大不同。

1. malloc(用户态内存分配)

  • 适用环境:用户空间(user space)

  • 函数原型void *malloc(size_t size);

  • 本质malloc 是 C 语言标准库函数,它的本质是通过系统调用(如 brkmmap)向操作系统申请内存。

  • 特点

    • 位于用户空间,不能直接访问内核资源。

    • 分配的是虚拟内存,由操作系统的内存管理机制(如页表)进行映射。

    • 返回的地址对于当前进程是有效的,但其他进程无法直接访问。

malloc 使用方便,但在内核模块里是不能使用的(因为内核模块运行在内核态)。

2. kmalloc(内核态物理连续内存分配)

  • 适用环境:内核空间(kernel space)

  • 函数原型void *kmalloc(size_t size, gfp_t flags);

  • 本质kmalloc 是 Linux 内核提供的内存分配函数,用来分配物理上连续的一段内存。

  • 特点

    • 适合需要高速访问或者用于 DMA(直接内存访问)场景。

    • 分配的是物理上连续的一块内存,且虚拟地址连续。

    • 分配小块内存(一般不超过 128KB,实际受限于系统配置)。

    • 使用 GFP 参数(如 GFP_KERNELGFP_ATOMIC)控制分配行为。

    • 分配完后要用 kfree 释放。

kmalloc 适合小块、快速的内核态内存分配,但当内存碎片严重或者分配大块内存时容易失败。

3. vmalloc(内核态虚拟连续内存分配)

  • 适用环境:内核空间(kernel space)

  • 函数原型void *vmalloc(unsigned long size);

  • 本质vmalloc 也是内核提供的分配接口,但它分配的是虚拟地址连续、物理地址不一定连续的内存。

  • 特点

    • 可以分配比 kmalloc 更大的内存块(比如几 MB 甚至更多)。

    • 分配的是虚拟地址连续的内存块,内部通过多个物理页进行映射。

    • 访问速度相对于 kmalloc 分配的内存会稍慢,因为需要额外的地址转换。

    • 适合用于大块但访问速度要求不高的内核内存。

    • 分配完要用 vfree 释放。

vmalloc 是解决大块内存申请需求的重要手段,虽然慢一点,但胜在大而稳定。

4. 总结对比表

特性mallockmallocvmalloc
使用空间用户空间内核空间内核空间
连续性虚拟地址连续虚拟+物理地址连续虚拟地址连续、物理不一定连续
速度很快相对较慢
大小适用范围小到大小(<128KB)大(MB甚至更多)
释放函数freekfreevfree
应用场景应用程序开发驱动开发/小内存块

驱动开发/大内存块

5. 小Tips

  • 在内核中,绝对不能使用 malloc!要用 kmallocvmalloc

  • 如果你需要的内存小且需要物理连续(比如 DMA),就用 kmalloc

  • 如果你需要的内存比较大,且对访问速度要求不那么高,就用 vmalloc

  • kmalloc + GFP_ATOMIC 是紧急情况下(比如中断处理)使用的快速分配,不可睡眠。

  • 记得配对释放malloc -> freekmalloc -> kfreevmalloc -> vfree

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值