傻傻分不清楚 kmalloc、vmalloc和malloc之间有什么区别以及实现上的差异

kmalloc、vmalloc 和 malloc 的区别及实现差异详解

这三者都是内存分配函数,但适用于不同场景(内核空间或用户空间),在内存连续性、实现机制和适用场景上有显著差异。以下是详细对比:

 

1. kmalloc

定位:Linux 内核空间的物理连续内存分配器。

内存连续性:

物理地址连续:分配的内存在物理内存中是连续的。

虚拟地址连续:虚拟地址空间也是连续的。

实现原理:

基于 Slab/Slub 分配器:内核预先创建不同大小的缓存池(如 8B、16B、...、4KB),kmalloc 从最匹配的缓存中快速分配对象。

快速分配:使用 __get_free_pages() 从伙伴系统批量获取页帧,缓存到 Slab 中,避免频繁调用伙伴系统。

对齐要求:默认按 ARCH_KMALLOC_MINALIGN 对齐(通常为 8 字节)。

适用场景:

需要物理连续内存的场景(如 DMA 操作、硬件设备缓冲区)。

小内存分配(通常 ≤ 4MB)。

限制:

分配大内存可能失败(物理连续内存不足)。

不支持高端内存(Highmem)。

释放函数:kfree()

2. vmalloc

定位:Linux 内核空间的虚拟连续内存分配器。

内存连续性:

物理地址不连续:通过映射非连续的物理页帧实现。

虚拟地址连续:虚拟地址空间是连续的。

实现原理:

逐页映射:

用 alloc_page() 从伙伴系统获取多个不连续的物理页帧。

修改内核页表,将这些物理页映射到连续的虚拟地址空间(VMALLOC_START ~ VMALLOC_END)。

性能开销:涉及页表修改和 TLB 刷新,分配速度慢于 kmalloc。

适用场景:

分配超大内存块(如内核模块加载、大型缓冲区)。

不需要物理连续性的场景(如软件层的数据缓存)。

限制:

不能用于 DMA:硬件设备无法访问物理不连续的内存。

访问速度较慢(TLB Miss 概率高)。

释放函数:vfree()

3. malloc

定位:用户空间的动态内存分配器(C 库函数)。

内存连续性:

虚拟地址连续:在进程的虚拟地址空间中连续。

物理地址不确定:物理内存可能不连续(由内核透明管理)。

实现原理:

基于系统调用:

brk/sbrk:扩展堆内存(小内存分配)。

mmap:创建匿名映射分配大内存(≥128KB 默认阈值)。

内存管理器:

glibc ptmalloc:通过空闲链表(Free List)管理内存块,减少系统调用次数。

分块策略:将大内存分割为 Chunk,复用释放的块以减少碎片。

适用场景:

用户态程序的通用内存分配。

大小不限的内存请求(受进程地址空间限制)。

释放函数:free()

核心区别对比表

特性 kmalloc vmalloc malloc

适用空间 内核空间 内核空间 用户空间

物理连续性 ✔️ 连续 ❌ 不连续 ❌ 不连续(由内核管理)

虚拟连续性 ✔️ 连续 ✔️ 连续 ✔️ 连续

实现基础 Slab 分配器 + 伙伴系统 直接修改页表 + 伙伴系统 brk/mmap + 用户态内存管理器

分配速度 快(缓存机制) 慢(页表操作) 中等(需用户态管理)

最大内存 较小(通常 ≤4MB) 较大(受 VMALLOC 区域限制) 极大(受虚拟地址空间限制)

硬件交互支持 ✔️ 支持(DMA 等) ❌ 不支持 ❌ 不适用

内存对齐 按对象大小对齐(如 8B) 按页对齐(如 4KB) 通常按 8B 或 16B 对齐

典型应用 设备驱动、小对象缓存 内核模块、大型数据缓冲区 用户程序动态内存

使用示例

// kmalloc(内核空间)

char *buf = kmalloc(1024, GFP_KERNEL); // 分配 1KB 物理连续内存

kfree(buf);

 

// vmalloc(内核空间)

void *ptr = vmalloc(1024 * 1024); // 分配 1MB 虚拟连续内存

vfree(ptr);

 

// malloc(用户空间)

int *arr = malloc(sizeof(int) * 100); // 用户空间分配数组

free(arr);

总结

kmalloc:追求速度和物理连续性,适用于内核小内存和硬件交互场景。

vmalloc:牺牲性能换取大块虚拟连续内存,适用于软件层大数据处理。

malloc:用户空间的通用分配器,依赖内核系统调用和库函数管理。

在开发内核模块时,优先使用 kmalloc(除非需分配超大内存);在用户空间开发时,malloc 是唯一选择。物理连续性要求是区分 kmalloc 和 vmalloc 的关键!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux技术芯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值