Linux关于地址空间和MMAP映射有何特点
Linux采用
虚拟
内存技术,系统中的所有进程之间以虚拟方式共享内存。对每个进程来说,它们好像都可以访问整个系统的所有物理内存。更重要的是,即使单独一个进程,它拥有的地址空间也可以远远大于系统物理内存。
进程地址空间由每个进程中的线性地址区组成,每个进程都有一个32位或64位的平坦(flat)空间,空间的具体大小取决于体系结构。“平坦”指地址空间范围是一个独立的连续区间。通常情况下,每个进程都有唯一的这种平坦空间,而且每个进程的地址空间之间彼此互不相干。两个不同的进程可以在它们各自地址空间的相同地址内存存放不同的数据。但是进程之间也可以选择共享地址空间,我们称这样的进程为线程。
在地址空间中,我们更为关心的是进程有权访问的虚拟内存地址区间,比如08048000~0804c000。这些可被访问的合法地址区间被成为内存区域(memory area),通过内核,进程可以给自己的地址空间动态地添加或减少内存区域。
进程只能访问有效范围内的内存地址。每个内存区域也具有相应进程必须遵循的特定访问属性,如只读、只写、可执行等属性。如果一个进程访问了不在有效范围中的地址,或以不正确的方式访问有效地址,那么内核就会终止该进程,并返回“段错误”信息。
内存区域可以包含各种内存对象,如下:
可执行文件代码的内存映射,成为代码段(text section)。
可执行文件的已初始化全局变量的内存映射,成为数据段(data section)。
包含未初始化全局变量的零页(也就是bss段)的内存映射。零页是指页面中的数据全部为0。
用于进程用户空间栈的零页的内存映射。
每一个诸如C库或动态链接程序等共享库的代码段、数据段和bss也会被载入进程的地址空间。
任何内存映射文件。
任何共享内存段。
任何匿名的内存映射,比如由malloc()分配的内存。
进程地址空间的任何有效地址都只能位于唯一的区域,这些内存区域不能相互覆盖。可以看到,在执行的进程中,每个不同的内存片断都对应一个独立的内存区域:栈、对象代码、全局变量、被映射的文件等等。
内核使用内存描述符表示进程的地址空间。内存描述符由mm_struct结构体表示,定义在文件中,该结构包含了和进程地址空间有关的全部信息。
VMA
内存区域由vm_area_struct结构体描述,定义在文件中,内存区域在内核中也经常被称作虚拟内存区域或者VMA。
VMA标志是一种位标志,它定义在vm_area_struct结构中(该结构中的vm_flags子域)。和物理页的访问权限不同,VMA标志反映了内核处理页面索需要遵守的行为准则,而不是硬件要求。VM_IO标志内存区域中包含对设备I/O空间的映射。该标志通常在设备驱动程序执行 mmap()函数进行I/O空间映射时才被设置,同时该标志也表示该内存区域不能被包含在任何进程的存放转存(core dump)中。VM_RESERVED标志内存区域不能被换出,它也是在设备驱动程序进行映射时被设置。
vm_area_struct结构体中的vm_ops域指向与指定内存区域相关的操作函数表,内核使用表中的方法操作VMA。
mmap()和do_mmap():创建地址区间
内核使用do_mmap()函数创建一个新的线性地址区间。但是说给函数创建一个新VMA并不非常准确,因为如果创建的地址区间和一个已经存在的地址区间相邻,并且它们具有相同的访问权限的话,那么两个区间将合并为一个。如果不能合并,那么就确实需要创建一个新的VMA了。但无论哪种情况,do_mmap()函数都会将一个地址区间加入到进程的地址空间中——无论是扩展已经存在的内存区域还是创建一个新的区域。
do_mmap()函数声明在文件中,原型如下:
unsigned long do_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long offset)
在用户空间可以通过mmap()函数调用获取内核函数do_mmap()的功能。mmap()系统调用原型如下:
void *mmap2(void *start, size_t length,
int prot, int flags,
int fd, off_t pgoff)
do_munmap()函数从特定的进程地址空间中删除指定地址区间,该函数在文件中声明:
int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
系统调用munmap()给用户空间程序提供了一种从自身地址空间中删除指定地址区间的方法,它和系统调用mmap()的作用相反:
int munmap(void *start, size_t length)
mmap设备操作
对于驱动程序来说,内存映射可以提供给用户程序直接访问设备内存的能力。映射一个设备,意味着使用户空间的一段地址关联到设备内存上。无论何时,只要程序在分配的地址范围内进行读取或者写入,实际上就是对设备的访问。
并不是所有的设备都能进行mmap抽象。例如,串口设备和其他面向流的设备就无法实现这种抽象。mmap的另一个限制是映射都是以 PAGE_SIZE为单位的。内核只能在页表一级处理虚拟地址;因此,被映射的区域必须是PAGE_SIZE的整数倍,而且必须位于起始于 PAGE_SIZE整数倍地址的物理内存内。如果区域的大小不是页大小的整数倍,内核就通过生成一个稍微大一些的区域来容纳它。
mmap方法是file_operations结构中的一员,并且在执行mmap系统调用时就会调用该方法。在调用实际方法之前,内核会完成很多工作,而且该方法的原型与系统调用的原型由很大区别。关于Linux命令的介绍,看看《linux就该这么学》,具体关于这一章地址3w(dot)linuxprobe/chapter-02(dot)html
文件操作声明如下:
int (*mmap) (struct file * filp, struct vm_area_struct *vma);
其中vma参数包含了用于访问设备的虚拟地址区间的信息。大部分工作已经由内核完成了,要实现mmap,驱动程序只要为这一地址范围构造合适的页表即可,如果需要的话,就用一个新的操作集替换vma->vm_ops。
有两种建立页表的方法:使用remap_page_range函数可一次建立所有的页表,或者通过nopage VMA方法每次建立一个页表。
构造用于映射一段物理地址的新页表的工作是由remap_page_range完
linux中ioremap和mmap的区别
本篇文章主要介绍一下在maegnto里cache(File System, APC, Memcached, Redis)的使用,及在不同的服务器环境中改怎么使用让其性能达到最佳。
理解magento的Two-Level Caching
magento默认使用zend framework的二层缓存存储方式。就是说它使用两层结构对cache进行配合管理,一个快的,但大小有限制的结构是一层比如APC或者Memcached ,一个比较慢的结构作为第二层比如file system.每一种存储结构各有利弊,要不同情况不同分析使用,APC 和 Memcached 是使用 key/value来存储cache,他们都不支持tag。File system 和Redis 支持tag.
magento二级缓存结构工作流程图示 (Thanks to Fabrizio Branca):
magento自带的各种后端缓存介绍:
File system (var/cache)
默认情况下,Magento 将它的缓存条目存储在file系统中,在var/cache/下可查看。这种情况很适合小型的,数据量不大的站点。但是对于大型的站点,随着浏览量的不断增多,对file的读写操作也将越来越多,站点也会越来越慢。magento是由tags来对cache进行组织管理的,这意味着可以对某一个cache组(相同的tag为一个group)进行操作。
优点:这是默认的,不需要装额外的软件
缺点:清除cache依赖于tag,通常修改某个product或处理某个order完之后,对应的前台页面都需要更新缓存。每次更新缓存时,都需要根据tag进行所有条目即file进行查找,试想如果站点有多于1000个product,整个cache的大小将会大于50MB,大约有3500个file,你能想象到每次更新cache都要对3500个file进行查找有多慢吗。
小提示
1:使用 SSD 替代普通硬盘
2:把var/cache接入 tmpfs
----------------------------------------------------------------------------------------------------------------------------------
APC – Alternative PHP Cache (Key/Value)
APC是一个免费,开源且强健的框架用来缓存和优化 PHP 的中间代码。
优点:相对于file cache system是很快了
缺点:不支持tag,所以依然需要file system作为slow level cache。服务器需要安装PHP APC 模块
小提示:确保有足够的内存给APC ,可在 php.ini 中修改参数apc.shm_size
Configuration (app/etc/local.xml)
...
apc
mgt_
...
Settings for php.iniapc.enabled = 1
apc.optimization = 0
apc.shm_segments = 1
apc.shm_size = 768M
apc.ttl = 48000
apc.user_ttl = 48000
apc.num_files_hint = 8096
apc.user_entries_hint = 8096
apc.mmap_file_mask = /tmp/apc.XXXXXX
apc.enable_cli = 1
apc.cache_by_default = 1
apc.max_file_size = 10M
apc.include_once_override = 0
---------------------------------------------------------------------------------------------------------------------------
Memcached (Key/Value)
Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。
优点:更快的存取速度
缺点:不支持tag,所以依然需要file system作为slow level cache
需求:1:Memcached server 2: PHP extension for memcached
Configuration (app/etc/local.xml)
...
memcached
...
---------------------------------------------------------------------------------------------------------------------
Redis – Advanced key-value store with full cache tag support
magento允许我们使用redis server作为中央存储仓库,它支持tag的使用,所以不再需要file system作为slow level cache。在多服务器多站点环境中,强烈推荐使用redis
,用一个中央缓存仓库,对所有server cache进行管理。
优点:快;支持tag;已在一个日均ip为500000的站点做过测试,性能极好且稳定。
需求:1:服务器上需要装Redis 2:PHP 扩展 phpredis 需要安装 3:Magento扩展“Cm_Cache_Backend_Redis”需要安装
Installation
1. Install redis (2.4+ required)
2. Install phpredis
3. Install the magento extension “Cm_Cache_Backend_Redis”
4. Edit your app/etc/local.xml
...
Cm_Cache_Backend_Redis
127.0.0.1
6379
0
0
1
0
1
1
20480
gzip
...
转载仅供参考,版权属于原作者。祝你愉快,满意请采纳哦
你不是已经说了区别
ioremap是将物理地址转换为虚拟地址
mmap是将设备内存线性地址映射到用户地址空间
linux的线程只能访问虚拟地址,不管是不是内核,ioremap应用,比如有个寄存器地址是0xe8000000
你要用ioremap映射后,才能访问地址0xe8000000。这两个地址是不同的,mmu会帮你搞定,对你是透明的
mmap在内核我用过ops中的mmap方法
我写过一个例程,见附件。里面还有用户态的测试程序。
鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!