参考:http://blog.csdn.net/tigerjb/article/details/6412881
http://linux.chinaunix.net/techdoc/system/2008/06/16/1011365.shtml
http://www.xiangmocheng.com/2009/09/kmalloc-vmalloc-malloc-difference/
http://blog.csdn.net/gxfan/article/details/2723455
http://www.360doc.com/content/11/1201/10/1317564_168823458.shtml
Linux源码情景分析——毛德操
参考网站上给出了kmalloc和vmalloc的用法和区别,本文从kmalloc和vmalloc实现的角度来分析二者的不同:
首先来看kmalloc和vmalloc的实现(linux2.4内核)
void * kmalloc (size_t size, int flags) { cache_sizes_t *csizep = cache_sizes; for (; csizep->cs_size; csizep++) { if (size > csizep->cs_size) continue; return __kmem_cache_alloc(flags & GFP_DMA ? csizep->cs_dmacachep : csizep->cs_cachep, flags); } BUG(); // too big size return NULL; }
void * __vmalloc (unsigned long size, int gfp_mask, pgprot_t prot) { void * addr; struct vm_struct *area; size = PAGE_ALIGN(size); if (!size || (size >> PAGE_SHIFT) > num_physpages) { BUG(); return NULL; } area = get_vm_area(size, VM_ALLOC); if (!area) return NULL; addr = area->addr; if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, gfp_mask, prot)) { vfree(addr); return NULL; } return addr; }
我们清楚地看到,kmalloc从通用缓冲区中申请空间,而vmalloc则无此要求,它利用普通的申请页面的函数进行申请,
重点在其对页面的虚拟地址是有要求的:VMALLOC_START~4GB
malloc最终调用do_brk(),在用户空间的堆栈中申请空间,不过do_brk做“批发”,malloc做“零售”
mmap()将一个已经打开的文件的内容映射到他的用户空间,使得能够像访问内存一样访问文件。
当需要分配一个不具有专用slab队列的数据结构而不必为之使用整个页面时,就应该通过kmalloc分配
,这些一般都是些细小而又不常用的数据结构,如果数据结构大小接近一个页面,则应该直接通过
alloc_pages为之分配一个页面;函数vmalloc从内核的虚存空间(3G)分配一块虚存以及相应的物理内存,
类似与系统调用brk()。不过brk()是由进程在用户控件启动并从用户控件分配的,而vmalloc则是在系统空间
,也就是内核启动,从内核空间分配的。由vmalloc分配的空间不会被kswapd换出,因为kswapd只扫描各个
进程的用户空间,而根本看不到通过vmalloc分配到 页面表项。至于通过kmalloc分配的数据结构,则kswapd
只是从各个slab队列中寻找和收集空闲不用的slab,并释放占用的页面,但是不会将尚在使用的slab所占据
的页面换出。