array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 Linux地址映射--线性映射与非线性映射 - 爱码网

一,线性映射与非线性映射

1.       内存管理

物理内存管理:

Linux内存最小管理单位为页(page),通常一页为4K。初始化时,linux会为每个物理内存也建立一个page的管理结构,操作物理内存时实际上就是操作page页。某些设备会映射在物理内存地址外,这些地址会在使用时建立page结构。

 

进程内存管理:

Linux进程通过vma进行管理,每个进程都有一个task_struct结构体进行维护,其中的mm_struct结构体管理这进程的所有内存。Mm_struct中维护者一个vma链表,其中的每一个vma节点对应着一段连续的进程内存。这里的连续是指在进程空间中连续,物理空间中不一定连续。如果使用malloc等申请一段内存,则内核会给进程增加vma节点。

 

2.       为何内核与进程空间不重合

进程:0~3G

内核:3G~4G

进程与内核合起来使用了4G的地址空间,而不是各自使用4G空间,获得的好处是进程进入内核是不需要切换页表,降低了进出内核的消耗。

 

2.6内核中,所有进程的内核空间(3G~4G)都是共享的。

Linux启动后,第一个进程是init进程,它的页表与内核页表是一致的,系统中的其他所有进程都是init进程的儿子或后代。Linux中进程创建通过fork()实现,子进程的PGDPTE是父进程的拷贝此时会把内核进程的页表拷贝到每个进程中。在各个进程的运行过程中,他们的页表可能会发生变化,比如发生缺页异常。如果是进程页表发生改变,则只要改变进程的页表项(0G~3G)就够了,如果是内核页表发生变化,则必须通知到所有进程改变各自维护的一份内核页表(3G~4G)。最简单的方法是每次内核页表改变后,遍历所有进程去改变他们维护的内核页表,显然效率很低。Linux内核通过page fault机制实现内核页表的一致。内核页表改变时,只改变init进程的内核页表。当进程访问该页时,会发生一个缺页异常,异常处理中通过init进程更新当前进程的内核页表。

Linux地址映射--线性映射与非线性映射

3.       非线性区域

非线性区与线性区是内核地址空间中的概念。

对于非线性区存在,可以做如下的解释。

Linux物理内存空间分为DMA内存区(DMA Zone)、低端内存区(Normal Zone)与高端内存区(Highmem Zone)三部分。DMA Zone通常很小,只有几十M。低端内存区与高端内存区的划分源于linux内核空间大小的限制。

Linux内核只有1G的空间,通常内核把物理内存与其地址空间做了线性映射,也就是一一映,这样可以提高内存访问速度。

当内存超过1G时,线性访问机制就不够用了,只能有1G的内存可以被映射,剩余的内存无法被内核使用。当然无法忍受。

为了解决这一问题,linux把内核分为线性区与非线性区两部分。线性区规定最大为896M,剩下的为非线性区。与线性区不同,非线性区不会提前进行内存映射,而是在使用时动态映射。线性区映射的物理内存成为低端内存,剩下的内存被称为高端内存。

假设物理内存为2G,则地段的896M为低端内存,通过线性映射给内核使用。其他的1128M内存为高端内存,可以被内核的非线性区使用。由于要使用128M非线性区来管理超过1G的高端内存,所以通常都不会映射,只有使用时才使kmap映射,使用完后要尽快用kunmap释放。

使用128M管理1G的内存是不是有点小马拉大车的感觉?其实不会,因为高端内存的大部分要进程使用。

对于物理内存为1G的内核,系统不会真的分配896M给线性空间,896M最大限制。下面是一个1.5G物理内存linux系统的真实分配情况,只有721M分配给了低端内存区,如果是1Glinxu系统,分配的就更少了。

MemTotal   1547MB

HighTotal     825MB

LowTotal     721MB

申请高端内存时,如果高端内存不够了,linux也会去低端内存区申请,反之则不行。

 

4.       linux管理之外的物理地址空间(other Addr

理论上,32位系统可管理的物理地址空间为4Gx86架构多一些io空间。计算机系统中的每个设备都是要占用一定的物理地址空间的,如PCI设备,所以不会把4G都给内存,这也意味着32位系统无法支持4G内存。

对于这部分物理内存之外的物理地址空间,这段空间不知道应该怎么称呼,这里暂时称为Device Zone

由于Device Zone没有被linux管理,也就不会为它建立page结构来管理,因此linux中使用该段内存时都是直接使用其物理地址,而使用物理内存则是通过向linux申请free page来实现。同样道理,这块肯定也不会映射到线性区,而是使用ioremap映射到非线性区域,或直接用mmap映射到进程空间

http://blog.chinaunix.net/uid-20528014-id-314322.html

相关文章: