内存管理八 内存分配接口总结

xiaoxiao2025-07-31  24

一、简介:  

  内存分配的接口有很多,不同的申请函数有不同的功能,下面会做详细的介绍和对比。

kmalloc:基于slab分配器,用于分配小内存,物理空间连续的内存块;vmalloc:用于分配大内存,虚拟地址连续的内存;malloc:为用户空间分配进程地址空间(即分配一块VMA);mmap:用户空间分配内存、读写大文件和加载静态库等;

  可以用下图清晰的表明:

二、详细说明:

1、kmalloc(size_t size, gfp_t flags):

(1)kmalloc基于slub分配器,分配物理地址连续的小内存;

(2)gfp_mask常用标志:

进程上下文,可以睡眠 GFP_KERNEL进程上下文,不可以睡眠 GFP_ATOMIC中断处理程序 GFP_ATOMIC软中断 GFP_ATOMICTasklet GFP_ATOMIC用于DMA的内存,可以睡眠 GFP_DMA | GFP_KERNEL用于DMA的内存,不可以睡眠 GFP_DMA | GFP_ATOMIC

(3)kfree(const void *ptr)   释放由kmalloc()分配出来的内存块;

2、vmalloc(unsigned long size):

(1)vmalloc 用于分配内核空间里连续虚拟地址的大内存块,分配的大小要以页面大小对齐(4Kb);

(2)vmalloc的函数如下:

void *vmalloc(unsigned long size) { return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); } vmalloc -> __vmalloc ->__vmalloc_node static void *__vmalloc_node(unsigned long size, unsigned long align, gfp_t gfp_mask, pgprot_t prot, int node, const void *caller) { return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END, gfp_mask, prot, 0, node, caller); }

  以上GFP_KERNEL | __GFP_HIGHMEM说明有效从High memory区域开始分配,分配的区域在

VMALLOC_START -VMALLOC_END之间,关于vmalloc的区域看查看内存管理五中查看。

(3)void vfree(void *addr)

   用于释放vmalloc申请的内存,这个函数可以睡眠,因此不能从中断上下文调用。

3、void *malloc(size_t size):

(1)malloc是用户空间用户分配内存的接口;

(2)malloc分配函数分配空间分如下两种情况:

  testA通过malloc申请100Byte的内存时,其实是为用户空间分配进程地址空间(分配一块VMA),

在使用到buf的空间时,CPU才会触发缺页中断,在缺页中断中一页一页的分配物理内存;

  testB在申请内存时,申请的虚拟内存都已经分配了物理内存并建立了页表映射;

void testA(void) { char *bufA = malloc(100); * bufA = 100; } void testB(void) { char *bufB = malloc(100); mlock(buf, 100); }

(3)malloc对于用户空间的使用非常简单,但在内核空间会经过很多的处理,下面引用一张图可以清晰的表明:

4、void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset):

(1)mmap/munmap是用户空间常用的系统调用接口,用于用户程序分配内存、读写大文件、链接

动态库文件等;

(2)prot参数表示映射页面的读写权限:

PROT_EXEC //页内容可以被执行PROT_READ //页内容可以被读取PROT_WRITE //页可以被写入PROT_NONE //页不可访问

(3)flags参数:指定映射对象的类型,映射选项和映射页是否可以共享。

 

作者:frank_zyp 您的支持是对博主最大的鼓励,感谢您的认真阅读。 本文无所谓版权,欢迎转载。

转载请注明原文地址: https://www.6miu.com/read-5034012.html

最新回复(0)