理解CPU内存管理
概述:从设计层面理解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内存管理的更多相关文章
- Intel X86 32位CPU内存管理----《Linux内核源码情景分析》笔记(一)
Intel X86 32位CPU内存管理 在X86系列中,8086和8088是16为处理器,而从80386开始为32为处理器,80286则是该系列从8088到80386,也就是16位处理器到32位处理 ...
- 深入理解Android内存管理原理(六)
一般来说,程序使用内存的方式遵循先向操作系统申请一块内存,使用内存,使用完毕之后释放内存归还给操作系统.然而在传统的C/C++等要求显式释放内存的编程语言中,记得在合适的时候释放内存是一个很有难度的工 ...
- 你应该这样理解JVM内存管理
在进行Java程序设计时,一般不涉及内存的分配和内存回收的相关代码,此处引用一句话: Java和C++之间存在一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外的人想进去,墙里面的人想出来 ,个人从这 ...
- OC 知识:彻底理解 iOS 内存管理(MRC、ARC)
1. 什么是内存管理 程序在运行的过程中通常通过以下行为,来增加程序的的内存占用 创建一个OC对象 定义一个变量 调用一个函数或者方法 而一个移动设备的内存是有限的,每个软件所能占用的内存也是有限的 ...
- 深入理解 Linux 内存管理
1. 内存地址 以Intel的中央处理器为例,Linux 32位的系统中.物理内存的基本单位是字节(Byte),1个字节有8个二进制位. 每一个内存地址指向一个字节,内存地址加1后得到下一个字节的地址 ...
- 深入理解C++内存管理机制
关于C++的内存处理,可分为三大块,分别是: (一)内存管理机制 (二)内存泄露处理 (三)内存回收机制 这篇文章将就(一)内存管理机制 进行深入探讨,如有错误欢迎大家指正. C++的内存管理也可细分 ...
- 深入理解Aarch64内存管理
本文是对learn_the_architecture_-_aarch64_memory_management的部分翻译和个人注解.个人英文水平有限,若有翻译不当,欢迎加我私人微信LinuxDriver ...
- [转载]对iOS开发中内存管理的一点总结与理解
对iOS开发中内存管理的一点总结与理解 做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作 ...
- Spark内存管理机制
Spark内存管理机制 Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行 ...
随机推荐
- 多线程访问winform控件出现异常的解决方法
一. 多线程访问winform控件出现异常的解决方法 1. 问题描述<1> 如果创建某控件的线程之外的其他线程试图调用该控件,则会引发一个 InvalidOperationExcept ...
- SRV记录说明
SRV记录是DNS服务器的数据库中支持的一种资源记录的类型,它记录了哪台计算机提供了哪个服务这么一个简单的信息 SRV 记录:一般是为Microsoft的活动目录设置时的应用.DNS可以独立于活动 ...
- android142 360 分页加载
dao: package com.itheima.mobileguard.db.dao; import java.util.ArrayList; import java.util.List; impo ...
- BI之ETL学习(一)kettle
最近开始折腾数据,起源是多业务数据源需要转换到数据分析平台.这个过程需要跨机器,跨库.同时还需要将业务数据表的内容进行转换,合并,清洗等等操作. 经过多方选型,最终决定使用kettle来作为数据抽取处 ...
- freeswitch 配置 DID 方法
本文来自 csdn http://blog.csdn.net/voipmaker 转载注明出处,谢谢. 我建了一个 Freeswitch学习 交流群, 45211986, 欢迎加入. DI ...
- 利用 Composer 完善自己的 PHP 框架(二)——发送邮件
本教程示例代码见 https://github.com/johnlui/My-First-Framework-based-on-Composer 回顾 上一篇文章中,我们手工建造了一个简易的视图加载器 ...
- 让 BAT 的 Offer 不再难拿
随着各大公司春招的开始,很多小伙伴都行动起来了,我有幸能够加入百度并和大家分享自己的经验心得.由于我面试的都是比较大的公司,所以自然也是做了这方面的准备,因此这篇总结并不一定适合想去创业公司的同学.另 ...
- View绘制详解(五),draw方法细节详解之View的滚动/滑动问题
关于View绘制系列的文章已经完成了四篇了,前面四篇文章主要带小伙伴们熟悉一下View的体系的整体框架.View的测量以及布局等过程,从本篇博客开始,我们就来看看View的绘制过程.View的绘制涉及 ...
- PostgreSQL解决"Abc_de_fghijkl_mn" 首字母小写去掉下划线并且下划线后面的第一个字母大写或首字母大写去掉下划线并且下划线后面的首字母大写的js
select "lower"(substr('Abc_de_fghijkl_mn', 1, 1)) || substr(replace(REGEXP_REPLACE(INITCAP ...
- (转载)MatLab绘图
转载自:http://www.cnblogs.com/hxsyl/archive/2012/10/10/2718380.html 转载自:http://www.cnblogs.com/jeromebl ...