1 kmalloc()
static __always_inline void *kmalloc(size_t size, gfp_t flags)
falgs:
kzalloc()
同kmalloc一样,只是分配的内存预先被清零
2 vmalloc()
void *vmalloc(unsigned long size)
可以分配到很大的的虚拟内存,但是不是连续的内存
void vfree(const void *addr)
{
kfree(addr);
}
3 后备高速缓存(内存池)
在驱动程序中,会经常反复地分配很多同一大小的内存块,也会频繁的将这些内存块给释放掉。如果频繁的申请和释放内存,很容易产生内存碎片,使用内存池很好地解决了这个问题。在Linux中,为一些反复分配和释放的结构体预留了一些内存空间,使用内存也来管理,管理这种内存池的技术叫做slab分配器。这种内存叫做后备高速缓存。
struct kmem_cache {
unsigned int size, align;
unsigned long flags;
const char *name;
void (*ctor)(void *);
};
创建高速缓冲池:
struct kmem_cache *kmem_cache_create(const char *name, size_t size,
size_t align, unsigned long flags, void (*ctor)(void *))
该函数创建一个新的后备告诉缓存对象,这个缓冲区中可以容纳指定个数的内存块。
内存块的数目由参数size来指定。
参数name表示该后备高速缓存对象的名字,以后可以使用name来表示使用哪个后备高速缓存。
第3个参数align是后备高速缓存中第一个对象的偏移值,这个值一般情况下被置为0。
第4个参数flage是一个位掩码,表示控制如何完成分配工作。
第5个参数ctor是一个可选的函数,用来对加入后备告诉缓存中的内存块进行初始化。
分配slab对象的函数:
void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
释放:
void kmem_cache_free(struct kmem_cache *cachep, void *objp)
销毁缓存池
void kmem_cache_destroy(struct kmem_cache *c)
实例代码:
用来为线程结构体分配一点内存
#define INFO_NUM 6 //表示要分配一个能装的下6个 struct thread_info 结构体的缓冲池
struct thread_info *ti;/*线程结构体指针*/
/*以下两行创建slab缓存*/
static struct kmem_cache *thread_info_cache;/*声明一个struct kmem_cache的指针*/
thread_info_cache = kmem_cache_create ("thread info", sizeof(struct thread_info)*INFO_NUM, 0, 0, NULL);
/*创建一个后备高速缓存区*/
/*以下分配slab缓存*/
ti = kmem_cache_alloc (thread_info_cache, GFP_KERNEL); /*分配一个结构体*/
/*省略了使用slab缓存的函数 ....../
/*以下两行释放slab缓存*/
kmem_cache_free (thread info cache, ti);/*释放一个结构体*/
kmem_cache_destroy (thread_info_cache);/*销毁一个结构体*/
上面的API可以快速的分配内存,但是在实际的驱动中,我们更多的是用kmalloc,kzalloc。来简单快速的分配和释放若干字节,为此内核专门创建了一些常见的字节大小的对象高速缓存,通过下面的命令可以得到
cat /proc/slabinfo | grep kmalloc
dma-kmalloc-8192 0 0 8192 4 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-4096 0 0 4096 8 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-2048 0 0 2048 16 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-1024 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-512 64 64 512 64 8 : tunables 0 0 0 : slabdata 1 1 0
dma-kmalloc-256 0 0 256 64 4 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-128 0 0 128 64 2 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-64 0 0 64 64 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-32 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-16 0 0 16 256 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-8 0 0 8 512 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-192 0 0 192 42 2 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-96 0 0 96 42 1 : tunables 0 0 0 : slabdata 0 0 0
kmalloc-8192 341 348 8192 4 8 : tunables 0 0 0 : slabdata 87 87 0
kmalloc-4096 187 208 4096 8 8 : tunables 0 0 0 : slabdata 26 26 0
kmalloc-2048 419 448 2048 16 8 : tunables 0 0 0 : slabdata 28 28 0
kmalloc-1024 2045 2176 1024 32 8 : tunables 0 0 0 : slabdata 68 68 0
kmalloc-512 18266 18688 512 64 8 : tunables 0 0 0 : slabdata 292 292 0
kmalloc-256 8857 9856 256 64 4 : tunables 0 0 0 : slabdata 154 154 0
kmalloc-192 25901 27552 192 42 2 : tunables 0 0 0 : slabdata 656 656 0
kmalloc-128 2612 2944 128 64 2 : tunables 0 0 0 : slabdata 46 46 0
kmalloc-96 3248 3318 96 42 1 : tunables 0 0 0 : slabdata 79 79 0
kmalloc-64 19794 20928 64 64 1 : tunables 0 0 0 : slabdata 327 327 0
kmalloc-32 11309 12032 32 128 1 : tunables 0 0 0 : slabdata 94 94 0
kmalloc-16 5888 5888 16 256 1 : tunables 0 0 0 : slabdata 23 23 0
kmalloc-8 7680 7680 8 512 1 : tunables 0 0 0 : slabdata 15 15 0
内核创建了很多8字节,16字节等大小的对象高速缓存,就是kmalloc,kzalloc