内核内存分配

在应用程序中,常使用malloc函数进行动态内存分配,而在Linux内核中,通常使用kmalloc来动态分配内存。

kmalloc 原型是:
#include <linux/slab.h>
void *kmalloc(size_t size, int flags)

参数:
size:要分配的内存大小。
flags:分配标志, 它控制 kmalloc 的行为。

1、最常用的标志是GFP_KERNEL(内部最终通过调用 __get_free_pages 来进行, 它是 GFP_ 前缀的来源),它的意思是该内存分配是由运行在内核态的进程调用的。

也就是说,调用它的函数属于某个进程的,当空闲内存太少时,kmalloc函数会使当前进程进入睡眠,等待空闲页的出现。

2、如果kmalloc是在进程上下文之外调用,比如在中断处理,任务队列处理和内核定时器处理中。这些情况属于中断上下文,不能进入睡眠,

这时应该使用优先权GFP_ATOMIC。

3、GFP_ATOMIC
用来在进程上下文之外的代码(包括中断处理)中分配内存,从不睡
眠。
4、GFP_KERNEL
进程上下文中的分配。可能睡眠。(16M-896M)
5、__GFP_DMA
这个标志要求分配能够 DMA 的内存区(物理地址在16M以下的页
帧 )
6、__GFP_HIGHMEM
这个标志表示分配的内存位于高端内存。(896M以上)

用kfree函数来释放kmalloc分配的内存

如果模块需要分配大块的内存,那使用面向页的分配技术会更好

get_zeroed_page(unsigned int flags)
返回指向新页面的指针,并将页面清零。

__get_free_page(unsigned int flags)
和get_free_page类似,但不清零页面。

__get_free_pages(unsigned int flags,unsigned int order )
分配若干个连续的页面,返回指向该内存区域的指针,但也不清零这段内存区域。

当程序用完这些页, 可以使用下列函数之一来释放它们:

void free_page(unsigned long addr)
void free_pages(unsigned long addr, unsigned
long order)

如果释放的和先前分配数目不等的页面,会导致系统错误

时间: 2024-10-09 15:17:01

内核内存分配的相关文章

linux内核内存分配(三、虚拟内存管理)

在分析虚拟内存管理前要先看下linux内核内存的详细分配我开始就是困在这个地方,对内核内存的分类不是很清晰.我摘录其中的一段: 内核内存地址 =========================================================================================================== 在linux的内存管理中,用户使用0-3GB的地址空间,而内核只是用了3GB-4GB区间的地址空间,共1GB:非连 续空间的物理映射就位于3G

linux内核内存分配(二、struct slab和struct kmem_cache)

前一篇bloglinux内核内存分配(一.基本概念)主要是分析linux内核内存的分配和物理页分配函数接口.但是在实际的操作中,不一定所有内存申请都需要一个物理页,很多只是需要分配几K大小的内存就可以.所以就需要更小的内存分配函数.刚开始看这个有点不懂,不过懂了就很简单了.哈哈. slab思想 摘抄<深入linux设备驱动程序内核机制>的一段话:slab分配器的基本思想是,先利用页面分配器分配出单个或者一组连续的物理页面,然后在此基础上将整块页面分割成多个相等的小内存单元,以满足小内存空间分配

linux内核内存分配

实验要求: 1.编写一个内核模块,在模块中分配内存并访问 2.理解并验证kmalloc.vmalloc等函数的区别. 背景知识: 1.Linux内存页管理 Linux内核管理物理内存是通过分页机制实现的,它将整个内存划分成4K大小页,作为使分配和回收内存的基本单位.在分配内存时尽量分配连续内存,避免TLB的刷新率过高.故此Linux采用了“伙伴“关系来管理空闲页框.因此空闲页面分配时也需要遵循伙伴关系.最小单位是2的幂倍页面大小.内核中分配空闲页框的基本函数是get_free_page/get_

linux内核内存分配(一、基本概念)

内存分配是linux比较复杂也是比较重要的部分,这个和ssd驱动很类似:物理地址和虚拟地址的映射关系.下面总结下最近看到的有关内存分配的内容和自己的理解: 1.一致内存访问和非一致内存访问 上图来自<深入linux设备驱动程序内核机制> 简单的说明下,UMA(一致内存访问 uniform memory access)可以很好的看到所有cpu访问内存的距离都是一样的(其实就是通过总线到内存的速度和距离都是一样的)所以就叫一致内存访问: 很显然右边的NUMA就是非一致内存访问,内存节点0是CPU0

[Linux内存]linux内存分配函数总结

linux内核相关 1,linux内核内存分配函数总结 单位 接口 算法 动态大小 kmalloc/kfree/krealloc/kcalloc 按大小组织的缓存数组 固定大小 kmem_cache_create/kmem_cache_destroykmem_cache_alloc/kmem_cache_free Slab[2] 2^n页 alloc_pages/free_pages__get_free_pages/__free_pages 伙伴算法,分配若干(物理连续)页面,返回指向该区域第一

内核中内存分配--关于高端内存

Linux把物理内存划分为了三个管理区, 分别为0-16MB的ZONE_DMA, 16-896MB的ZONE_NORMAL和高于896MB的ZONE_HIGHMEM也就是高端内存. 至于为什么这么划分, ZONE_DMA好理解, 因为ISA总线只能对前16MB进行DMA寻址, 这块要分出来不能乱用. 而ZONE_NORMAL和ZONE_HIGHMEM为什么从896MB区分呢? 这还得从物理地址和虚拟地址说起. 默认情况下, 内核空间是指3GB-4GB的虚拟地址, 用户空间则是0-3GB. 内核进

Linux内核中常见内存分配函数

1.原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分别为: l   页全局目录(Page Global Directory) l   页上级目录(Page Upper Directory) l   页中间目录(Page Middle Directory) l   页表(Page Table) 页全局目录包含若干页上级目录的地址,页上级目录又依次包含若干页中间目录

Linux内核中常见内存分配函数zz

https://blog.csdn.net/wzhwho/article/details/4996510 1.      原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分别为: l         页全局目录(Page Global Directory) l         页上级目录(Page Upper Directory) l         页中间目录(

jvm 内存分配 (转)

深入理解JVM-JVM内存模型 http://www.cnblogs.com/dingyingsi/p/3760447.html 我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU的交互,而CPU运转速度越来越快,磁盘远远跟不上CPU的读写速度,才设计了内存,用户缓冲用户IO等待导致CPU的等待成本,但是随着CPU的发展,内存的读写速度也远远跟不上CPU的读写速度,因此,为了解决这一纠纷,CPU厂商在每颗CPU上加入了高速缓存,用来缓解这种症状,因此,现在CP