Linux high memory 学习总结
在free命令中有个参数l,它表示 show detailed low and high memory statistics。其实最先是对High Memory总是为零有些不解(Linux是64为)。其实更不解的是关于low memory、high memory。那么关于low memory和high memory是怎么一回事呢?如下截图所示:
一直对这个概念不解,直到看到关于linux kernel里的high memory 这篇文章。下面文字全部摘自这篇文章:
今天有人问我linux kernel里的high memory是怎么回事,说的比较乱,现在整理下。
high memory只存在于32位kernel下,以下文字都针对32位kernel。
1)什么是high memory,为什么要有high memory
Linux人为的把4G虚拟地址空间(32位地址最多寻址4G)分为3G+1G,其中0~3G为用户程序地址空间,3G~4G为kernel地址空间(为什么要这么分?为什么用户程序和kernel不能各自独享4G虚拟地址空间?这两个问题下次再说吧,这里不表),这就是说kernel最多寻址1G的虚拟地址空间。
当CPU启用MMU的paging机制后,CPU访问的是虚拟地址,然后由MMU根据页表转换成物理地址。页表是由kernel维护的,所以kernel可以决定1G的虚拟地址空间具体映射到什么物理地址。但是kernel最多只有3G~4G这1G地址空间,所以不管kernel怎么映射,最多只能映射1G的物理内存。所以如果一个系统有超过1G的物理内存,在某一时刻,必然有一部分kernel是无法直接访问到的(这个一定要想清楚,不然无法明白high memory)。另外,kernel除了访问内存外,还需要访问很多IO设备。在现在的计算机体系结构下,这些IO设备的资源(比如寄存器,片上内存等)一般都是通过MMIO的方式映射到物理内存地址空间来访问的,就是说kernel的1G地址空间除了映射内存,还要考虑到映射这些IO资源--换句话说,kernel还需要预留出一部分虚拟地址空间用来映射这些IO设备(ioremap就是干这个的)。
Linux kernel采用了最简单的映射方式来映射物理内存,即把物理地址+3G按照线性关系直接映射到kernel空间。考虑到一部分kernel虚拟地址空间需要留给IO设备(以及一些其他特殊用途),Linux kernel最多直接映射896M物理内存,而预留了最高端的128M虚拟地址空间给IO设备(还有其他的用途)。所以,当系统有大于896M内存时,超过896M的内存kernel就无法直接访问到了(想明白了么?),这部分内存就是high memory。那kernel就永远无法访问到超过896M的内存了马?不是的,kernel已经预留了128M虚拟地址,我们可以用这个地址来动态的映射到high memory,从而来访问high memory。所以预留的128M除了映射IO设备外,还有一个重要的功能是提供了一种动态访问high memory的一种手段(kmap主要就是干这个的,当然还有vmalloc)。
当然,在系统物理内存<896M,比如只有512M的时候,就没有high memory了,因为512M的物理内存都已经被kernel直接映射。事实上,在物理内存<896M时,从3G+max_phy ~ 4G的空间都作为上述的预留的内核地址空间(未考证)。
要理解high memory,关键是把物理内存管理,虚拟地址空间管理,以及两者间的映射(页表管理)三个部分分开考虑,不要把物理内存管理和虚拟地址空间管理混在一起。比如high memory也参与kernel的物理内存分配,你调用get_page得到的物理页有可能是low memory,也可以是high memory,这个物理页可以被映射到kernel,同时也可以被映射到user space。再比如vmalloc,只保证返回的虚拟地址是在预留的vmalloc area里,对应的物理内存,可以是low memory,也可以是high memory。当然出于性能考虑,kernel可能会优先分配直接映射的low memory,但我们不能假设high memory就不会被分配到。
一些结论:
1)high memory针对的是物理内存,不是虚拟内存,更确切的,虚拟地址空间。
2)high memory也是被内核管理的(有对应的page结构),只是没有映射到内核虚拟地址空间。当kernel需要分配high memory时,通过kmap等从预留的地址空间中动态分配一个地址,然后映射到high memory,从而访问这个物理页。
3)high memory和low memory一样,都是参与内核的物理内存分配,都可以被映射到kernel地址空间,也都可以被映射到user space地址空间。
4)物理内存<896M时,没有high memory,因为所有的内存都被kernel直接映射了。
5)64位系统下不会有high memory,因为64位虚拟地址空间非常大(分给kernel的也很大),完全能够直接映射全部物理内存。
2)题外话1 -- 关于最高端的128M内核虚拟地址(或者当物理内存<896M时更大)的分配:
这部分地址空间被划分为4段,分别是fixed mapping,kmap area,vmalloc area,还有8M用来catch kernel指针错误。其中fixed mapping主要用在boot阶段用来永久性映射一些物理地址固定的数据结构或者硬件地址(比如ACPI表,APIC地址,等等)。kmap area是kernel用来临时建立映射来访问物理页用的,可用的地址空间也比较小。128M中绝大部分reserve了给vmalloc area,vmalloc和ioremap返回的都是这个空间里的地址。
另外,在《Understanding the Linux Virtual Memory Manager》这本书中有linux 进程地址空间划分的详细图,很不错,我就懒得画了。
参考资料:
http://blog.sina.com.cn/s/blog_6488248f0100wu6v.html
http://blog.csdn.net/acs713/article/details/8575235
Linux high memory 学习总结的更多相关文章
- Linux内存管理学习资料
下面是Linux内存管理学习的一些资料. 博客 mlock() and mlockall() system calls. All about Linux swap space 逆向映射的演进 Linu ...
- Linux 目录结构学习与简析 Part1
linux目录结构学习与简析 by:授客 QQ:1033553122 说明: / linux系统目录树的起点 =============== /bin User Bi ...
- Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号
Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号 背景 上一讲我们介绍了Unix IPC中的2种管道. 回顾一下上一讲的介绍,IPC的方式通常有: Unix IPC包括:管道 ...
- Linux 系统编程 学习:04-进程间通信2:System V IPC(1)
Linux 系统编程 学习:04-进程间通信2:System V IPC(1) 背景 上一讲 进程间通信:Unix IPC-信号中,我们介绍了Unix IPC中有关信号的概念,以及如何使用. IPC的 ...
- 20135231 —— Linux 基础入门学习
20135231 何佳 学习计时:共12小时 读书:5 代码:2 作业:2 博客:3 一.学习目标 1. 能够独立安装Linux操作系统 2. 能够熟练使用Linux系统的基本命令 3. 熟练使用Li ...
- Linux系统新手学习的11点建议
随着Linux应用的扩展许多朋友开始接触Linux,根据学习Windwos的经验往往有一些茫然的感觉:不知从何处开始学起.这里介绍学习Linux的一些建议. 一.从基础开始:常常有些朋友在Linux论 ...
- Linux进程间通信IPC学习笔记之同步二(SVR4 信号量)
Linux进程间通信IPC学习笔记之同步二(SVR4 信号量)
- Linux进程间通信IPC学习笔记之同步二(Posix 信号量)
Linux进程间通信IPC学习笔记之同步二(Posix 信号量)
- Linux进程间通信IPC学习笔记之消息队列(SVR4)
Linux进程间通信IPC学习笔记之消息队列(SVR4)
随机推荐
- Web Api中的get传值和post传值
GET 方式 get方式传参 我们一般用于获取数据做条件筛选,也就是 “查” 1.无参 var look = function () { $.ajax({ type: "GET", ...
- ZooKeeper----Java实例文档
**************************************************************************************************** ...
- PHP旧系统基于命名空间重构经验
命名空间其实只是一个形式,最终目的是重构代码,但这个过程想要一蹴而就是不可能的. 一开始给了一个伪命题:基于ThinkPHP的重构(不要问为什么).经过一段的实践,发现这是一个大错特错的思维方式,其中 ...
- Oracle数据库建表并用SQL编程分等级
--创建学生表create table XS_543 ( XH char(6) not null , XM varchar2(20) not null, ZYM varchar2(10), XB ch ...
- Dubbo入门
早就听说了dubbo的好处,但是在项目中一直没有使用的机会,所以一直不知道怎么使用.今天晚上有空,简单的学习一下 就当入个门,以后项目中遇到的话,那么使用起来就比较简单了,至于介绍的话,我就不总结了, ...
- a标签,img标签,表格
<a></a> a标签,超链接标签 ,引入超链接方式: src="...." target="blank" 打开方式--新页 ...
- idea配置maven并添加镜像配置
1.打开maven存放文件夹找到 conf ->settings.xml 找到<mirrors>节点把下面内容写入节点内 配置为阿里云的镜像 <mirror> <i ...
- UVA 11582 Colossal Fibonacci Numbers! 大斐波那契数
大致题意:输入两个非负整数a,b和正整数n.计算f(a^b)%n.其中f[0]=f[1]=1, f[i+2]=f[i+1]+f[i]. 即计算大斐波那契数再取模. 一开始看到大斐波那契数,就想到了矩阵 ...
- 关于linux下DB2创建数据库报错问题
公司业务需要,把服务搭在中标下,在中标下装了DB2 Express-C v9.7.1,之前用着没有问题,隔了一段时间没用,最近又需要用到它,出了一些菜鸟问题,记录下来以免有人和我犯同样的错误...进入 ...
- 神奇的Bank系统之旅哦
奋斗不能等待,我们不能等到垂暮之年再去“全力以赴”.让我们从现在开始,为理想而努力,为人生而拼搏.精诚所至,金石为开,相信奋斗会让我们的青春之花绽放得更加绚烂,让我们的人生之路走下来不留遗憾. ...
