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)
随机推荐
- .NET vs2010中使用IrisSkin2.dll轻松实现winForm窗体换肤功能
IrisSkin2.dll是一款很不错的免费皮肤控件,利用它可以轻松的实现winForm窗体换肤! 网上很多朋友说在VS2010中不能使用IrisSkin2.dll,我这里提供一个取巧的办法. Iri ...
- 组件Newtonsoft.Json实现object2json转换
很多情况下,我们需要把数据类型做一些转换,供其它外部的子系统调用. 最为典型的是生成json格式供javascript作调用. 现成的组件Newtonsoft.Json可以实现object2json之 ...
- PagerTabStrip及自定义的PagerTab
如图是效果图 开发中经常会用到上面是一个Tab下面是一个ViewPager(ViewPager再包含几个Fragment),当点击Tab或是滑动ViewPager,Tab及ViewPager ...
- java 四舍五入保留小数
// 方式一: double f = 3.1516; BigDecimal b = new BigDecimal(f); double f1 = b.setScale(2, BigDecimal.RO ...
- Thinkphp 用PHPExcel 导入Excel
搞了个简单的Excel导入, 用的是PHPExcel(百科:用来操作Office Excel文档的一个PHP类库, 基于微软的OpenXML标准和PHP语言) 好, 不说了, 开始吧... 首先得有P ...
- javascript之八——BOM
8.1 window对象 BOM的核心对象是window--表示浏览器的一个实例.window有双重角色: 是通过javascript访问浏览器窗口的一个接口: 是ECMAScript规定的Globa ...
- WinForm 窗体应用程序(初步)之一
学习制作一个WinForm程序,有两样东西是需要首先掌握的.第一部分,我们称之为属性面板.无论是窗体还是控件,都有着自己的属性面板.第二部分,则是我们称之为控件的东西. 我们先来讨论一下属性面板.新建 ...
- i++,++i,Math.max,hasOwnPrototype.ajax,indexOf(),firefox的一些东西,jquery的contains函数,window.open
一.i++与++i的区别 1 var i=0;3 console.log(i++)5 0 1 var j=0; 2 3 console.log(++j) 4 1 a=++i;相当于i=i+1;a=i; ...
- go语言最新版本 下载地址
国内官方网站无法打开.放在了百度云中,定期会更新: 链接:http://pan.baidu.com/s/1dD59duh 密码:46ek 备用地址:http://pan.baidu.com/s/1hq ...
- Web Audio API_基本概念
Audio Context 音频的工作环境.类比做化学实验,Audio Context 就是为我们提供各种仪器和材料的实验室(严格地来说制造这些仪器材料的方法和工具也一并提供了).通常来说做实验一间实 ...
