在现代的层次结构中, 存储器是信息处理的来源与归宿, 占据重要位置. 但是, 在现有技术条件下, 任何一种存储装置, 都无法同时从速度与容量两方面, 满足用户的需求. 实际上它们组成了一个速度由快到慢, 容量由小到大的存储装置层次.
逻辑地址与物理地址
存储共享
存储保护与安全
内存 “扩充”
程序处理的基本过程
- 决定装入方式
程序中所使用的绝对地址, 可以编译或汇编时给出, 也可以由程序员直接赋予. 但在由程序员直接给出绝对地址时, 不仅要求程序员熟悉内存的使用的情况, 而且一旦程序或数据被修改后, 可能要改变程序中的所有地址. 因此通常是宁可在程序中采用符号地址, 然后再编译或汇编时, 在将这些符号地址转化为绝对地址
- 可重入定位装入方式
静态可重定位装入方式和动态可重定位装入方式
静态可重定位装入方式不允许程序在装入之后的运行过程中发生内存位置的移动
动态可重定位装入方式及动态重定位过程通常需要一定的硬件机构支持以使地址转换不影响指令执行速度.
- 动态运行时装入方式
动态运行时的装入程序, 在把装入模块转入内存后, 并不立即把装入模块中的相对地址转换为绝对地址, 而是把这种地址转换推辞到程序真正要执行时才进行
- 静态链接方式
- 装入时动态链接
- 运行时动态链接
这种链接方式是将对某些模块的链接推迟到执行时才执行, 即, 在执行过程中,当发现一个被调用模块尚未装入内存时, 立即由 OS 去找到该模块并将之装入内存, 把它链接到调用者模块上. 凡在执行过程中未被用到的目标模块, 都不会被调入内存和链接到装入内存, 这样不仅可加快程序的装入过程, 而且可节省大量内存空间
把作业地址空间中使用的逻辑地址变为内存空间中的物理地址的过程, 又称为地址 映射
- 重定位的类型
静态重定位: 当用户程序被装入内存时一次性实现逻辑地址到物理地址的转换, 以后不在转换(一般在装入内存时由软件完成) 作业i在执行前一次变址, 直到该作业完成退出内存为止.
动态重定位
在程序运行过程中药访问数据时再进行地址变换, 由地址变换机构进行的地址变换, 硬件上需要重定位寄存器的支持
连续内存分配: 每个进程位于一个连续的内存空间
工作流程
单一连续区分配采用静态分配和静态重定位方式, 即作业或进程一旦进入主存, 就一直等到它运行结束后才能释放主存
存储保护
分区式管理是满足多道程序的最简单的存储管理方案。它的基本思想是将内存划分若干个连续区域,称为分区。分区只能存储一个程序,而程序也只能在它所驻留的分区中运行。
- 固定分区
预先把可分配的主存储区空间分割成若干个连续区域, 称为一个分区. 每个分区的大小可以相同也可以不同. 但分区大小固定不变, 每个分区装一个且只能装一个作业
存储分配: 如果有一个空闲区, 则分配给进程
- 内存分配管理
通过设置内存分配表, 内存分配简单
缺点: 内存利用率不高
- 分区分配中的数据结构
(1) 空闲分区链
系统设立空闲分区链表: 每个空闲块的前后两个单元, 放置必要的说明信息和指针. 系统只要设立一个链首指针, 指向第一个空闲块即可. 分配程序可以依照自由块链表, 来查找合适的空闲块进行分配
(2) 分区分配表
- 分区分配操作
(1) 分配内存
(2) 回收内存
- 分配算法
按空闲块链接的方式不同, 可以有以下四种算法:
- 碎片问题
碎片问题的解决
- 分区式存储管理的优缺点
2. 动态重定位的实现
4.可重定位分区的优缺点
以上讨论都是基于一个作业在主存中占据的是一个连续分区的假定, 为了支持结构化程序设计, 操作系统往往把一道作业分成若干片段(如子程序, 主程序, 数据组等). 这样, 片段之间就不需要连续了, 只要增加一些重定位寄存器, 就可以有效地控制一道作业片段之间的调用
为了防止一首作业有意或无意地破坏操作系统或其它作业. 一般来说, 没有硬件支持, 实现有效的存储保护是困难的. 通常采用:
保护过程 – 防止地址越界
基址寄存器: 存放起始地址
限长寄存器: 存放长度
界限寄存器保护
基址、限长寄存器保护
防止操作越权
对于允许多个进程共享的存储区域,每个进程都有自己的访问权限。如果一个进程对共享区域的访问违反了权限规定,则发生操作越权 即读写保护
保护键方式
- 页面和物理块
分页存储管理, 是将一个进程的逻辑地址空间分成若干个大小相等的片, 称为 页面或页, 并为各页加以编号. 相应的, 也把内存空间分成与页面相同大小的若干个存储块, 称为(物理)块或页框.
分页管理中页与页框的对应关系示意图
- 地址结构
分页地址中的地址结构如下:
对某特定机器, 其地址结构是一定的, 若给定一个逻辑地址空间的地址A, 页面的大小为L, 则页号P和页内地址d可按下式求得:
- 管理
页表
空快管理
内存的分配与回收
位示图法
为了找到N个自由块, 就需要搜索位示图, 找到N个 “0” 位, 再经过一个简单的运算就得知相应的快地址(物理地址), 存贮空间的分配和回收工作较为方便, {0,1} 转换.
盘块的分配
盘块的回收
内存的分配
- 快表
如果把页表放在主存中, 无疑会影响系统的性能, 这是因为每次访问主存, 首先必须访问页表, 读出页描述子, 之后根据形成的实际地址在访问主存, 这要使访问主存的次数加倍, 因而使总的处理速度明显下降.
为了解决这个问题, 人们采用一组硬件寄存器, 存放当前访问过的页的页描述子, 每次访问主存时, 首先查找快表, 若找到所需的页描述子, 则快速形成物理地址. 否则从页表中查找后形成物理地址, 同时把页描述子写入快表. 如果设计得到, 快表的命中率可以很高
现代的大多数计算机系统, 都支持非常大的逻辑地址空间( 2 32 2^{32} 232 ~ 2 64 2^{64} 264). 页表就变得非常大, 要占用相当大的内存空间. 可采用两个方法来解决这一问题: ① 采用离散分配方式来解决难以找到一块连续的大内存空间的问题; ② 只将当前需要的部分页表项调入内存, 其余的页表项仍驻留在磁盘上, 需要时再调入.
- 两级级页表
32 位 进程页表多大?
设: 页面大小为: 4K, 用户空间 4GB
则: 一个进程 1M 页
设: 每个内存块号 4 字节
则: 进程页表 1K 页, 共占 4M 内存空间
结论: 一个进程的页表的各页之间可以不用连续存放
解决: 页表本身使用地址索引 – 页目录
- 多级级页表
64位 进程页表多大?
设: 页表大小为4K
则: 一个进程 2 52 2^{52} 252 页
设: 每个内存块号 4字节
则: 进程页表 2 42 ( 2 52 ÷ 2 10 ) 2^{42} (2^{52} \div 2^{10}) 242(252÷210) 页, 两级页表不能接受
结论: 必须采用三级以上的多级页表
- 反置页表
在分页存储管理系统重, 作业的地址空间是一维线性的, 这破坏了程序内部天然的逻辑结构, 造成共享, 保护的困难. 引入分段存储管理方式, 主要是为了满足用户和程序的下述需要:
- 段表
- 硬件支持
- 地址变换机构
- 分页和分段的主要区别
分段管理的优缺点
产生背景: 结合了段式与页式二者优点, 克服了二者的缺点
基本思想
用户程序划分: 按段式划分 (对用户来讲, 按段的逻辑关系进行划分; 对系统讲, 按页划分每一段)
内存划分: 按页式存储管理方案
内存分配: 以页为单位进行分配
- 管理
- 地址空间和地址结构
一个程序首先被划分成若干程序段, 每一段给予不同的分段标识符然后, 对每一分段又分成若干个固定大小的页面. 系统中的一个作业的地址空间结构页面尺寸为 4 K 字节, 该作业有三个分段, 第一段为 15K 字节, 占 4 页, 最后一页只有 1K 未用; 其他段同理. 未足一页大小的补为一页.
5.地址映射
- 地址变换
上述的地址变换要访问主存三次, 这将执行程序的速度大大降低, 为了解决上述问题, 可以采取"快表"技术
当内存空间紧张时, 系统将内存中某些进程暂时移到外存, 把外存中某些进程换进内存, 占据前者所占用的区域, 这种技术是进程在内存于外存之间的动态调度. 多用于分时系统中
何时需发生交换?
例子:
需要一个盘交换区: 必须足够大一存放所有用户程序的所有内存映象的拷贝; 必须对这些内存映象的直接存取
问题的提出:
虚拟存储器的基本思想是: 程序, 数据, 堆栈的大小可以超过内存的大小, 操作系统把程序当前使用的部分保留在内存, 而把其它部分保存在磁盘上, 并在需要时在内存和磁盘之间动态交换
虚拟存储器支持多到程序设计技术
程序局部性原理
在一段时间内一个程序的执行往往呈现出高度的局部
文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr
文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc
文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8
文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束
文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求
文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname
文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include<stdio.h>#include<string.h>#include<stdlib.h>#include<malloc.h>#include<iostream>#include<stack>#include<queue>using namespace std;typed_二叉树的建立
文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码
文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词
文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限
文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定
文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland