Linux内核下内存分配,Linux入门教程:Linux内核内存分配函数

vmalloc也有对应的vfree函数。

gfp_mask参数:

gfp_mask参数可以设置很多值,一下是各个取值的用处(直接引用至LKD):

GFP_ATOMIC  The allocation is high priority and must not sleep. This is the flag to use in interrupt handlers, in bottom halves, while holding a spinlock, and in other situations where you cannot sleep.

GFP_NOWAIT  Like GFP_ATOMIC, except that the call will not fallback on emergency memory pools. This increases the liklihood of the memory allocation failing.

GFP_NOIO  This allocation can block, but must not initiate disk I/O. This is the flag to use in block I/O code when you cannot cause more disk I/O, which might lead to some unpleasant recursion.

GFP_NOFS  This allocation can block and can initiate disk I/O, if it must, but it will not initiate a filesystem operation. This is the flag to use in filesystem code when you cannot start another filesystem operation.

GFP_KERNEL  This is a normal allocation and might block. This is the flag to use in process context code when it is safe to sleep. The kernel will do whatever it has to do to obtain the memory requested by the caller. This flag should be your default choice.

GFP_USER  This is a normal allocation and might block. This flag is used to allocate memory for user-space processes.

GFP_HIGHUSER  This is an allocation from ZONE_HIGHMEM  and might block. This flag is used to allocate memory for user-space processes.

GFP_DMA  This is an allocation from ZONE_DMA. Device drivers that need DMA-able memory use this flag, usually in combination with one of the preceding flags.

使用SLAB缓存分配:

当需要频繁的针对特定数据结构分配和释放内存时,为了避免反复内存分配和释放的开销,Linux内核提供了强大的内存缓存分配策略,即SLAB缓存分配。(实际上kmalloc函数就是建立在slab分配器上的!)

每个slab包含一定数量的对象,即需要被缓存的数据结构,每个slab都有三个状态:full,partial,empty。当试图从slab中分配一个object时,内核优先从partial的slab中获取对象,不行则从empty slab中,如果全部是full则创建一个新的slab。内核中管理slab缓存的组成主要有cache,slab,object,他们的关系可以用下图描述。

ea1173349dc0b583a4aec5e5a5ef1137.png

cache在内核中使用 kmem_cache结构来描述,包含三个链表--—slabs_full, slabs_partial, 以及slabs_empty。这些list中就包含相应状态的slab,slab在内核中的描述如下:

struct slab {

struct list_head  list;       /* full, partial, or empty list */

unsigned long     colouroff;  /* offset for the slab coloring */

void              *s_mem;     /* first object in the slab */

unsigned int      inuse;      /* allocated objects in the slab */

kmem_bufctl_t     free;       /* first free object, if any */

};

下列函数可以创建一个新的cache:

struct kmem_cache * kmem_cache_create(const char *name, size_t size,

size_t align, unsigned long flags, void (*ctor)(void *));

各个参数说明如下:

const char *name:cache的名称。

size_t size:cache中需要缓存的object的大小。

size_t align:slab中第一个object的偏移,一般0即可,使用标准对齐方式。

unsigned long flags:可以为缓存分配执行一些附加操作,没有的话直接0即可。

void (*ctor)(void *):cache的构造函数,你可以赋值一个函数地址,当新的page加入cache后一定会执行该构造函数。可以复赋值为NULL。

销毁一个cache时使用

int kmem_cache_destroy(struct kmem_cache *cachep);

内核提供两个函数负责从指定的cache获取和交还内存:

void * kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);

void kmem_cache_free(struct kmem_cache *cachep, void *objp);0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值