在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 学习总结的更多相关文章

  1. Linux内存管理学习资料

    下面是Linux内存管理学习的一些资料. 博客 mlock() and mlockall() system calls. All about Linux swap space 逆向映射的演进 Linu ...

  2. Linux 目录结构学习与简析 Part1

    linux目录结构学习与简析 by:授客 QQ:1033553122 说明: /             linux系统目录树的起点 =============== /bin      User Bi ...

  3. Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号

    Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号 背景 上一讲我们介绍了Unix IPC中的2种管道. 回顾一下上一讲的介绍,IPC的方式通常有: Unix IPC包括:管道 ...

  4. Linux 系统编程 学习:04-进程间通信2:System V IPC(1)

    Linux 系统编程 学习:04-进程间通信2:System V IPC(1) 背景 上一讲 进程间通信:Unix IPC-信号中,我们介绍了Unix IPC中有关信号的概念,以及如何使用. IPC的 ...

  5. 20135231 —— Linux 基础入门学习

    20135231 何佳 学习计时:共12小时 读书:5 代码:2 作业:2 博客:3 一.学习目标 1. 能够独立安装Linux操作系统 2. 能够熟练使用Linux系统的基本命令 3. 熟练使用Li ...

  6. Linux系统新手学习的11点建议

    随着Linux应用的扩展许多朋友开始接触Linux,根据学习Windwos的经验往往有一些茫然的感觉:不知从何处开始学起.这里介绍学习Linux的一些建议. 一.从基础开始:常常有些朋友在Linux论 ...

  7. Linux进程间通信IPC学习笔记之同步二(SVR4 信号量)

    Linux进程间通信IPC学习笔记之同步二(SVR4 信号量)

  8. Linux进程间通信IPC学习笔记之同步二(Posix 信号量)

    Linux进程间通信IPC学习笔记之同步二(Posix 信号量)

  9. Linux进程间通信IPC学习笔记之消息队列(SVR4)

    Linux进程间通信IPC学习笔记之消息队列(SVR4)

随机推荐

  1. .NET vs2010中使用IrisSkin2.dll轻松实现winForm窗体换肤功能

    IrisSkin2.dll是一款很不错的免费皮肤控件,利用它可以轻松的实现winForm窗体换肤! 网上很多朋友说在VS2010中不能使用IrisSkin2.dll,我这里提供一个取巧的办法. Iri ...

  2. 组件Newtonsoft.Json实现object2json转换

    很多情况下,我们需要把数据类型做一些转换,供其它外部的子系统调用. 最为典型的是生成json格式供javascript作调用. 现成的组件Newtonsoft.Json可以实现object2json之 ...

  3. PagerTabStrip及自定义的PagerTab

    如图是效果图      开发中经常会用到上面是一个Tab下面是一个ViewPager(ViewPager再包含几个Fragment),当点击Tab或是滑动ViewPager,Tab及ViewPager ...

  4. java 四舍五入保留小数

    // 方式一: double f = 3.1516; BigDecimal b = new BigDecimal(f); double f1 = b.setScale(2, BigDecimal.RO ...

  5. Thinkphp 用PHPExcel 导入Excel

    搞了个简单的Excel导入, 用的是PHPExcel(百科:用来操作Office Excel文档的一个PHP类库, 基于微软的OpenXML标准和PHP语言) 好, 不说了, 开始吧... 首先得有P ...

  6. javascript之八——BOM

    8.1 window对象 BOM的核心对象是window--表示浏览器的一个实例.window有双重角色: 是通过javascript访问浏览器窗口的一个接口: 是ECMAScript规定的Globa ...

  7. WinForm 窗体应用程序(初步)之一

    学习制作一个WinForm程序,有两样东西是需要首先掌握的.第一部分,我们称之为属性面板.无论是窗体还是控件,都有着自己的属性面板.第二部分,则是我们称之为控件的东西. 我们先来讨论一下属性面板.新建 ...

  8. 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; ...

  9. go语言最新版本 下载地址

    国内官方网站无法打开.放在了百度云中,定期会更新: 链接:http://pan.baidu.com/s/1dD59duh 密码:46ek 备用地址:http://pan.baidu.com/s/1hq ...

  10. Web Audio API_基本概念

    Audio Context 音频的工作环境.类比做化学实验,Audio Context 就是为我们提供各种仪器和材料的实验室(严格地来说制造这些仪器材料的方法和工具也一并提供了).通常来说做实验一间实 ...