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

一、简介:  

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

  • 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_ATOMIC
  • Tasklet 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
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文无所谓版权,欢迎转载。

猜你喜欢

转载自blog.csdn.net/frank_zyp/article/details/83380292