kmalloc、vmalloc、malloc的区别

简单的说:

  1. kmalloc和vmalloc是分配的是内核的内存,malloc分配的是用户的内存
  2. kmalloc保证分配的内存在物理上是连续的,vmalloc保证的是在虚拟地址空间上的连续,malloc不保证任何东西(这点是自己猜测的,不一定正确)
  3. kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相对较大
  4. 内存只有在要被DMA访问的时候才需要物理上连续
  5. vmalloc比kmalloc要慢

详细的解释:

对于提供了MMU(存储管理器,辅助操作系统进行内存管理,提供虚实地址转换等硬件支持)的处理器而言,Linux提供了复杂的存储管理系统,使得进程所能访问的内存达到4GB。

进程的4GB内存空间被人为的分为两个部分--用户空间与内核空间。用户空间地址分布从0到3GB(PAGE_OFFSET,在0x86中它等于0xC0000000),3GB到4GB为内核空间。

内核空间中,从3G到vmalloc_start这段地址是物理内存映射区域(该区域中包含了内核镜像、物理页框表mem_map等等),比如我们使用 的 VMware虚拟系统内存是160M,那么3G~3G+160M这片内存就应该映射物理内存。在物理内存映射区之后,就是vmalloc区域。对于 160M的系统而言,vmalloc_start位置应在3G+160M附近(在物理内存映射区与vmalloc_start期间还存在一个8M的gap 来防止跃界),vmalloc_end的位置接近4G(最后位置系统会保留一片128k大小的区域用于专用页面映射)

kmalloc和get_free_page申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在较简单的转换关系,virt_to_phys()可以实现内核虚拟地址转化为物理地址:
   #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
   extern inline unsigned long virt_to_phys(volatile void * address)
   {
        return __pa(address);
   }
上面转换过程是将虚拟地址减去3G(PAGE_OFFSET=0XC000000)。

与之对应的函数为phys_to_virt(),将内核物理地址转化为虚拟地址:
   #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
   extern inline void * phys_to_virt(unsigned long address)
   {
        return __va(address);
   }
virt_to_phys()和phys_to_virt()都定义在include/asm-i386/io.h中。

而vmalloc申请的内存则位于vmalloc_start~vmalloc_end之间,与物理地址没有简单的转换关系,虽然在逻辑上它们也是连续的,但是在物理上它们不要求连续。

我们用下面的程序来演示kmalloc、get_free_page和vmalloc的区别:
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
MODULE_LICENSE("GPL");
unsigned char *pagemem;
unsigned char *kmallocmem;
unsigned char *vmallocmem;

int __init mem_module_init(void)
{
//最好每次内存申请都检查申请是否成功
//下面这段仅仅作为演示的代码没有检查
pagemem = (unsigned char*)get_free_page(0);
printk("<1>pagemem addr=%x", pagemem);

kmallocmem = (unsigned char*)kmalloc(100, 0);
printk("<1>kmallocmem addr=%x", kmallocmem);

vmallocmem = (unsigned char*)vmalloc(1000000);
printk("<1>vmallocmem addr=%x", vmallocmem);

return 0;
}

void __exit mem_module_exit(void)
{
free_page(pagemem);
kfree(kmallocmem);
vfree(vmallocmem);
}

module_init(mem_module_init);
module_exit(mem_module_exit);

我们的系统上有160MB的内存空间,运行一次上述程序,发现pagemem的地址在0xc7997000(约3G+121M)、kmallocmem 地址在0xc9bc1380(约3G+155M)、vmallocmem的地址在0xcabeb000(约3G+171M)处,符合前文所述的内存布局。

http://blog.csdn.net/daniel_ice/article/details/6834316 vmallc实现原理

http://blog.csdn.net/macrossdzh/article/details/5958368

kmalloc、vmalloc、malloc的区别

时间: 2024-12-11 03:41:01

kmalloc、vmalloc、malloc的区别的相关文章

LINUX内核内存管理kmalloc,vmalloc

一.kmalloc与vmallco 在设备驱动程序或者内核模块中动态开辟内存,不是用malloc,而是kmalloc ,vmalloc,释放内存用的是kfree,vfree,kmalloc函数返回的是虚拟地址(线性地址). kmalloc特殊之处在于它分配的内存是物理上连续的,这对于要进行DMA的设备十分重要. 而用vmalloc分配的内存只是线性地址连续,物理地址不一定连续,不能直接用于DMA.vmalloc函数的工作方式类似于kmalloc,只不过前者分配的内存虚拟地址是连续的,而物理地址则

New与malloc的区别

http://blog.sina.com.cn/s/blog_6fc5bfa90100qgd7.html1,malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符.它们都可用于申请动态内存和释放内存. 2, 对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求.对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数.由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强

Samsung_tiny4412(笔记)--&gt;alloc_pages,kmalloc,vmalloc,kmem_cache,class

/*********************************************************************************** * * Samsung_tiny4412(笔记)-->alloc_pages,kmalloc,vmalloc,kmem_cache,class * * 声明: * 1. 本文中有些源代码没有全部帖出来,主要是因为篇幅太大的原因; * 2. 基于1中的原因,本文借鉴了python中的缩进代码风格进行代码的体现: * 1. 有些代码

C++内存分配new和malloc的区别

这里有一篇讲的很详细new和malloc的区别 总结一下: 1.new/delete是操作符,malloc/free是函数 2.malloc分配内存需指定大小,且只能是一般数据类型,分配成功返回void*,需要强制类型转换,分配失败返回NULL,需手动检查是否分配成功:new分配内存无需指定大小,可以为类对象,分配成功返回特定类型指针,分配失败抛出异常. 3.new分配内存,一般类型可以指定初始化,未初始化的保留其在内存中的原值:对象会调用其默认构造函数,也可以指定构造函数. 4.delete对

C++ new和malloc的区别

一.new和delete C语言提供了malloc和free两个系统函数,完成对堆内存的申请和释放.而C++则提供了两个关键字new和delete: 1.1 规则 new/delete是关键字,效率高于malloc和free. 配对使用,避免内存泄漏和多重释放. 避免交叉使用,比如malloc申请空间delete释放,new出的空间被free. new/delete 主要是用在类对象的申请和释放.申请的时候会调用构造器完成初始化,释放的时候,会调用析构器完成内存清理. 1.2 new/new[]

关于kmalloc vmalloc 和malloc

用户态的malloc是申请堆空间的用户态函数.可网上不少人以为malloc在内核态的调用函数是kmalloc或vmalloc,这是不对的 kmalloc是基于slab的,它在通用缓存区申请分配,通用缓存区一共26块缓存块,使用DMA和常规分配各占有13个. 当调用vmalloc时,先调用kmalloc(之所以没有直接使用专用缓存,是因为vmalloc调用本来就不是很频繁,而且开销有些大,需要建立页表到页框的映射,还要刷新tlb,)分配一块可以存放所申请物理页框数量的描述符的空间,最后直接调用al

Memory Allocation API In Linux Kernel &amp;&amp; Linux Userspace、kmalloc vmalloc Difference、Kernel Large Section Memory Allocation

目录 1. 内核态(ring0)内存申请和用户态(ring3)内存申请 2. 内核态(ring0)内存申请:kmalloc/kfree.vmalloc/vfree 3. 用户态(ring3)内存申请:malloc/free 4. 内核内存申请原则 5. 内核中分配物理地址连续的大段内存 1. 内核态(ring0)内存申请和用户态(ring3)内存申请  0x1: 差异点 在内核中申请内存和在用户空间中申请内存不同,有以下因素引起了复杂性,包括 1. 内核的虚拟和物理地址被限制到1GB 2. 内核

new和malloc的区别

一.malloc函数(memory allocation) 中文名:动态内存分配 原型:extern  void *malloc(unsigned int num_bytes); 说明:分配长度为num_bytes字节的内存块,分配成功,则返回指向该内存块的指针.否则指向NULL空指针,使用free()释放 1.1void *malloc (int size); 说明:向系统申请长度为size的内存,返回类型是void*型,但是可以强制转换成其他类型的指针. 也就是说当你申请内存的时候,系统还不

C++中new和malloc的区别

原文:http://blog.163.com/ji_wei8888/blog/static/4868044620117361747282/ 1.new 是c++中的操作符,malloc是c 中的一个函数 2.new 不止是分配内存,而且会调用类的构造函数,同理delete会调用类的析构函数,而malloc则只分配内存,不会进行初始化类成员的工作,同样free也不会调用析构函数 3.内存泄漏对于malloc或者new都可以检查出来的,区别在于new可以指明是那个文件的那一行,而malloc没有这些