概述:从设计层面理解CPU的内存模式,包括段式内存管理、页式内存管理以及虚拟化扩展内存管理。实际上,硬件支持与软件实现从来就不是能分开讲的,比如,Intel CPU架构师在选择CPU的硬件特性时,必然会站在软件的角度审视该特性。目前,硬件实现的许多特性完全可以由软件方式实现,但为何非要设计成硬件实现方式,其原因或许是因为硬件实现有助于系统整体的性能提高,亦或许受研究者的个体偏好等非技术性因素影响,本文不做深究。

CPU处理器的内存管理提供了段式内存管理和页式内存管理两种技术,OS在借助该内存管理技术实现了系统底层的内存管理功能。

我们知道,由于内存(RAM,主存,半导体材料)的访问速度远远超过硬盘存储介质(磁性材料),所以内存负责与CPU直接交互,程序运行之前其数据和代码需要被加载到内存之中。那么问题来了,“上帝”将待执行的程序加载到内存之中就OK了,为什么还要通过段/页式内存管理方式管理内存呢?要知道段页式内存管理技术会将一个给定的“内存地址”变来变去,非常繁琐,导致"当前程序“理解的内存地址与实际的物理内存地址的对应关系并不直观,为什么CPU/OS要采用这类内存管理方式呢?

如果”当前程序“理解的内存地址为A,对应的物理内存也是A,世界该是多么的直白……

我在学习操作系统之初就思考过这个问题,后来阅遍经卷、参悟CPU架构、自己开始实现一个OS内核之后才对这个问题理解得越来越深刻。

首先要知道一点,OS实现段/页式内存管理的说法存在一定的误导性,更准确的说法应该是,现代CPU架构设计支持了段页式内存管理设计,OS作为一个纯软件实体,如果想基于CPU提供的技术支持正常运行,就必须对段页式内存管理技术做出表态:用还是不用。实际上,段式管理是必须要有的,页式管理是可选的。

那么,为什么CPU架构要支持该类内存管理技术?这个问题的理解又要转到”软实体“的角度。

打个比方,我作为土豪一枚,我的机器配置了50G物理内存,OS欲将待运行的程序加载到这50G内存里面,该加载到内存的哪部分,或如何利用50G内存呢?

方式一:将整个程序全部加在到内存中,这50G内存都是该程序自己的,随便用!

这种内存管理方式最大的缺点就是,OS不能实现我们所说的”多任务“,即很难”同时“执行多个程序。如果用这种内存管理方式实现多任务支持,只能这样:OS加载程序A,A运行了0.1s后被暂停,OS将A的当前状态保存到磁盘,然后加载程序B,B运行0.1s后被暂停并被保存状态到磁盘,OS加载A,恢复A的执行状态并执行A 0.1s...

作为一种原始的内存使用和多任务方式,该方案粗暴、低效、资源浪费……你想怎么批评它就怎么批评它!

方式二:将50G按10G分成5部分,OS拿出其中四部分即40G空间加载4个程序并运行,任务切换只需要切换当前的CPU状态而不必重新加载目标程序。咦……OS瞬间支持4任务了……但是如果想支持8任务、10任务呢?难道针对一个不同的多任务需求需要定制不同的多任务OS吗?另外,任务之间的内存隔离也有问题,在0-10G内存空间里的程序可以直接访问到其他3个任务的内存空间数据(如果没有而外的硬件防护的话),好像安全性不敢保证,因为CPU在执行指令时如不借助”助手“将无法判断某个内存位置访问是否合法。

但是,这种方案确实有些进步,因为这种内存管理方式可以简单满足多任务需求了,而且,对比现代内存管理技术,该方案可以称之为”硬件级固定长度的段式内存管理“了。

方式三:现在,需要解决方式二的缺点,实现任意多任务和内存访问保护。

CPU架构师这样考虑(我猜的)的:

如果我把内存不按照定长分割,而是根据待加载的程序的大小,使用智能算法决定为它分配多大内存,这不就可以更好的实现多任务了嘛!

理论上只要物理内存足够大,就可以支持同时运行任意数量的任务。

程序间的内存保护(最起码任务程序不能越界访问其他任务的内存)该如何实现呢?

CPU架构师这样考虑(我猜的)的:

CPU在加载程序后,当前程序的内存首地址(基址)和内存长度保存到一张表里面,此时程序所理解得内存地址在CPU看来永远是一个相对于当前基址的偏移地址。

这样,程序访问内存是提供的内存地址紧紧是个CPU眼中的偏移而已,CPU就可以查表检查该偏移是否超过内存长度。

如果偏移合法,基址加偏移就可以得到真实的物理地址,然后取得数据;如果偏移不合法,CPU拒绝访问数据,并抛出异常。

如果你读过其他资料已经对段式内存管理有所了解,那么你应该会看出,方式三正是段式内存管理技术的雏形,CPU用到的表就是GDT/LDT。

待续。。。

理解CPU内存管理的更多相关文章

  1. Intel X86 32位CPU内存管理----《Linux内核源码情景分析》笔记(一)

    Intel X86 32位CPU内存管理 在X86系列中,8086和8088是16为处理器,而从80386开始为32为处理器,80286则是该系列从8088到80386,也就是16位处理器到32位处理 ...

  2. 深入理解Android内存管理原理(六)

    一般来说,程序使用内存的方式遵循先向操作系统申请一块内存,使用内存,使用完毕之后释放内存归还给操作系统.然而在传统的C/C++等要求显式释放内存的编程语言中,记得在合适的时候释放内存是一个很有难度的工 ...

  3. 你应该这样理解JVM内存管理

    在进行Java程序设计时,一般不涉及内存的分配和内存回收的相关代码,此处引用一句话: Java和C++之间存在一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外的人想进去,墙里面的人想出来 ,个人从这 ...

  4. OC 知识:彻底理解 iOS 内存管理(MRC、ARC)

    1. 什么是内存管理 程序在运行的过程中通常通过以下行为,来增加程序的的内存占用 创建一个OC对象 定义一个变量 调用一个函数或者方法 而一个移动设备的内存是有限的,每个软件所能占用的内存也是有限的 ...

  5. 深入理解 Linux 内存管理

    1. 内存地址 以Intel的中央处理器为例,Linux 32位的系统中.物理内存的基本单位是字节(Byte),1个字节有8个二进制位. 每一个内存地址指向一个字节,内存地址加1后得到下一个字节的地址 ...

  6. 深入理解C++内存管理机制

    关于C++的内存处理,可分为三大块,分别是: (一)内存管理机制 (二)内存泄露处理 (三)内存回收机制 这篇文章将就(一)内存管理机制 进行深入探讨,如有错误欢迎大家指正. C++的内存管理也可细分 ...

  7. 深入理解Aarch64内存管理

    本文是对learn_the_architecture_-_aarch64_memory_management的部分翻译和个人注解.个人英文水平有限,若有翻译不当,欢迎加我私人微信LinuxDriver ...

  8. [转载]对iOS开发中内存管理的一点总结与理解

    对iOS开发中内存管理的一点总结与理解   做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作 ...

  9. Spark内存管理机制

    Spark内存管理机制 Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行 ...

随机推荐

  1. MFC实现数独(1)

    雨天纷纷扰扰,数月里每日有雨,这个夏天不热,写这个数独的动机很简单:实践是最好的成长方式,想要获得自信,必有这么一遭,我躲不过.至于决定记录成博客,则是因为很久没有写文章,经常感觉脑海里很空白,屡次开 ...

  2. 虚拟机VMware里 windows server 2003 扩充C盘方法

    你会经常用windows server 2003 吗?应该不会吧,有时一些东西必须装在windows server 2003 上才能用,所以 用虚拟机把,好,装在虚拟机上,8G的C盘够你用吗,一个稍微 ...

  3. MEF 编程指南(九):部件生命周期

    理解 MEF 容器部件生命周期和实现是非常重要的事情.考虑到 MEF 关注可扩展应用程序.这变得尤为重要.生命期可以解释为期望部件的共享性(transitively, its exports)   共 ...

  4. VMM服务模板(虚机、APP)部署排错

    I won't focus this blog on how to create a service template but more on how you can track the change ...

  5. Spring生态

    1.简洁有力,干掉了j2ee容器层特别是ejb,spring在rod Johnson十几年前一个人单挑j2ee体系开始,到十年前开始大行其道至今,基本上是java开发领域的事实标准.从此大部分开发者去 ...

  6. 安卓Activity界面切换添加动画特效

    在Android 2.0之后有了overridePendingTransition() ,其中里面两个参数,一个是前一个activity的退出两一个activity的进入, @Override pub ...

  7. Android游戏开发之主角的移动与地图的平滑滚动

    人物移动地图的平滑滚动处理 玩过rpg游戏的朋友应该都知道RPG的游戏地图一般都比较大 今天我和大家分享一下在RPG游戏中如何来处理超出手机屏幕大小的游戏地图. 如图所示为程序效果动画图 地图滚动的原 ...

  8. PHP做好防盗链的基本思想 防盗链的设置方法

    盗链是指服务提供商自己不提供服务的内容,通过技术手段绕过其它有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其它服务提供商的服务内容,骗取最终用户的浏览和点击率.受益者不提供资源或提供 ...

  9. c语言中的unsigned 和 signed

    我们来一起看下,C语言中,对于Integer Type(整数形式)的unsigned与signed两种形式的区别,以及在内存中的存储方式是如何的 Integer type(整数形式)是C语言中的基本数 ...

  10. Helpers\Tags

    Helpers\Tags The tags helper is a collection of useful methods: Tags::clean($data) Clean function to ...