在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. SQLServer中游标是如何处理数据的?

    游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次以行或者多行前进或向后浏览数据的能力.我们可以把游标当作一个指针,它可以指定结果中的任何位置,然后允许 ...

  2. TreeView使用

    1.添加节点,实现拖拽功能 private void Form1_Load(object sender, EventArgs e) { TreeNode node1 = new TreeNode(); ...

  3. 使用exe4j打包Java程序

    工具: exe4j软件(云盘存) 可以运行的Java程序的jar包 打开我们已经安装好的exe4j软件,首先看到的是一个欢迎界面,我们直接[next]就可以了: 2 在第二步中我们选择[JAR in ...

  4. Java基础复习笔记系列 三

    前几节都是基础中的基础,从第三讲的笔记开始,每次笔记针对Java的一个知识块儿.  Java异常处理 1.什么是异常? 异常是指运行期出的错误.比如说:除以一个0:数组越界:读取的文件不存在. 异常处 ...

  5. [moka同学笔记]Yii2.0 modal的使用

    第一次使用,时候不明白什么原理,大概用了几次后,才模模糊糊搞清楚原来是怎么一回事,现在就把写过的代码,贴在下边. 1.在视图文件中, 第一步首先在index.php文件中 做了一个a链接的按钮 调用了 ...

  6. No suitable driver found for jdbc:mysql://localhost:3306/dmc

    1. 使用java jdbc直接连接数据库操作, 出现题中错误, 参考网上说法, 将mysql连接jar放入jre拓展底下 不再报错

  7. Cookie——Javascript

    基本的cookie操作有三种:读取.写入.删除. var CookieUtil = { //根据cookie的name获取相应的value.它会在document.cookie字符串中查找cookie ...

  8. VIRTUALBOX 虚拟机安装 OS X 10.9 MAVERICKS

    VIRTUALBOX 虚拟机安装 OS X 10.9 MAVERICKS 原文链接:http://bbs.weiphone.com/read-htm-tid-7625465.html 原文作者已经写的 ...

  9. Flex布局窥探(一)

    一.Flex布局是神马? Flex是Flexible Box的缩写,意为‘弹性布局’,用来为盒模型提供最大的灵活性. 任何容器都能被指定为Flex布局: .box{ display: flex; } ...

  10. js之如何获取css样式

    js之如何获取css样式   一.获取内联样式 1 <div id ="myDiv" style="width:100px;height:100px; border ...