kmalloc、vmalloc、malloc的区别

news/2024/7/20 13:36:51 标签: 操作系统, 内存管理, 运维

简单的说:

  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


http://www.niftyadmin.cn/n/1671470.html

相关文章

python networkx进行最短路径分析_python-Networkx:计算并存储图中到 pandas dataframe 的最短路径...

这是通过三种不同的步骤来做您想做的事情的一种方法,因此很容易遵循.>步骤1&#xff1a;从边缘列表中构建networkx图形对象.>步骤2&#xff1a;创建一个包含2列的 dataframe (对于该DF中的每一行,我们希望从e1列到e2中的实体的最短距离和路径)>步骤3&#xff1a;逐行查…

从纪念碑谷的收益看小而美的游戏的盈利困境

引文地址http://www.cocoachina.com/appstore/case/2014/0709/9074.html原文如下本文转自游戏小伙伴“我们必须承认错过了赚钱的机会。”Ustwo工作室游戏总监Neil McFarlad近日如是说3个月前他们推出的益智小游戏《纪念碑谷》在上架后不到1周的时间里就登上了App Store中国区付…

[Android学习笔记九] Android 开发中图片灰阶(黑白)显示

灰阶显示图片的典型应用就是用户头像&#xff0c;如用户在线头像显示彩色&#xff08;原图&#xff09;&#xff0c;不在线显示灰色&#xff08;黑白图&#xff09;。总结一点就是更加一张原始图片来通过颜色的过滤处理计算得到不同显示效果的图片。这方法的API主要位于&#x…

集成微信支付时遇到的问题

从微信开放平台下载了最新的sdk&#xff0c;在测试时却死活跳不到微信支付的页面。 检查微信appId已经注册成功&#xff0c;微信sign也正常&#xff0c;看起来没有什么不对的地方&#xff0c;最后查着原因是&#xff1a;在share SDK中也有一套微信的SDK &#xff0c; 估计这套S…

mysql批处理语句_MySQL批处理SQL语句

MySQL 支持批处理的模式执行一批SQL语句&#xff0c;下面的例子就是实验MySQL如何在windows下批处理执行SQL语句。create table test(id int,name varchar(20));insert into test values(1,‘watson‘);batchfile.txt里包含下面的一些SQL 语句&#xff0c;此文件放在windows系统…

SQL Server 2012笔记分享-57:数据文件和日志文件放置最佳实践

&#xff08;一&#xff09;数据文件 (data file)一个数据库可以有一个或多个数据文件其中默认最先创建并包含系统对象的文件称为主数据文件 (primary data file)默认扩展名.mdf&#xff0c;不可以被去除其他数据文件称为从属数据文件 (secondary data file)默认扩展名.ndf&…

mapinfo制作地图_Mapinfo常用功能图文讲解,通信必备技能

点击蓝字关注我们1、简介MapInfoProfessional是一套强大的基于Windows平台的地理信息系统软件。使用MapInfo Professional&#xff0c;商业分析专家和GIS专家可以方便的将数据和地理信息的关系直观的展现。MapInfo Professional为新老用户提供了在数据维护、可视化、数据展现、…

【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置攻击帧以及动画创建!【一】...

上周貌似没有写新的博文&#xff0c;那么今天Himi写个精品的博文奉献给童鞋们&#xff1b; &#xff08;不少童鞋说Himi的教程最近都没有源码放出。 &#xff0c;这里我解释下&#xff0c;一般我没有放出源码的博文那肯定已经将代码贴出来了&#xff0c;这点是肯定的&#xff0…