12.7-12.13学习笔记

虚拟存储器的三个重要功能:

  • 将主存看做是一个存储在磁盘上的地址空间的高速缓存,在主存中只保护活动区域。
  • 为每个进程提供了一致的地址空间,从而简化了存储器管理。
  • 保护了每个进程的地址空间不被其他进程破坏。

9.1 物理和普通寻址

  • 物理寻址:主存被组织成一个由M个连续的字节大小的单元组成的数组,依次类推的寻址方式称为物理寻址。
  • 虚拟寻址:CPU生成一个虚拟地址(VA)来访问主存,在被传送到存储器之前先转换成适当的物理地址。地址翻译通过CPU芯片上的存储器管理单元完成。

9.2 地址空间

地址空间是一个非负整数地址的有序集合:

{0,1,2,......}
  • 线性地址空间:地址空间中的整数是连续的。
  • 虚拟地址空间:CPU生成的虚拟地址。
  • 物理地址空间:与系统中的物理存储器的M个字节相对应。

9.3 虚拟存储器作为缓存的工具

VM系统将虚拟存储器分割为虚拟页,虚拟页面的集合分为三个不相交的子集:

  • 未分配的:系统还未分配的页,未存储数据,不占用磁盘空间。
  • 缓存的:当前缓存在物理存储器中的已分配页
  • 未缓存的:没有缓存在物理存储器中的已分配页。

页表

页表:将虚拟页映射到物理页,就是一个页表条目的数组。

PTE:由一个有效位和一个n位地址字段组成的,表明了该虚拟页是否被缓存在DRAM中。

页命中

当CPU读取一个字的时候,地址翻译硬件将虚拟地址作为一个索引来定位PTE,并从存储器中读取它。

缺页

  • 操作系统为每个进程提供了一个独立的页表,也就是一个独立的虚拟地址空间。
  • 抖个虚拟页面可以映射到同一个共享物理页面上。
  • 存储器映射:将一组连续的虚拟页映射到任意一个文件中的任意位置的表示法。

DRA缓存不命中称为缺页。在不命中发生时,换入页面的策略称为按需页面调度。

9.4 虚拟存储器作为存储器管理的工具

  • 操作系统为每个进程提供了一个独立的页表,也就是一个独立的虚拟地址空间。
  • 抖个虚拟页面可以映射到同一个共享物理页面上。
  • 存储器映射:将一组连续的虚拟页映射到任意一个文件中的任意位置的表示法。

9.5 虚拟存储器作为存储器保护的工具

  • SUP:表示进程是否必须运行在内核模式下才能访问该页
  • READ:读权限
  • WRITE:写权限

9.6 地址翻译

地址翻译是一个N元素的虚拟地址空间(VAS)中的元素和一个M元素的物理地址空间(PAS)之间的映射。

MAP:VAS→PAS∪空

MAP(A)=

  • A‘:如果虚拟地址A处的数据在PAS的物理地址A处‘
  • 空:如果虚拟地址A处的数据不在物理存储器中

CPU中的一个控制寄存器页表基址寄存器指向当前页表,n位的虚拟地址包含两个部分:一个p位的虚拟页面偏移(VPO) 和一个(n-p)位的虚拟页号,页表条目中的物理页页号和虚拟地址中的VPO串联起来,就得到了相应的物理地址。

利用TLB加速地址翻译

在MMU中包括了一个关于PTE的小的缓存,称为翻译后备缓冲器(TLB),其中每一行都保存着一个由单个PTE组成的块。

  • CPU产生一个虚拟地址。
  • MMU从TLB中取出相对应的PTE。
  • MMU将这个虚拟地址翻译成一个物理地址,并将它发送到高速缓存/主存。
  • 高速缓存/主存将所请求的数据字返回给CPU。

多级页表

用来压缩页表的常用方法是使用层次结构的页表。

9.8 存储器映射

Linux通过将一个虚拟存储器区域与一个磁盘上的对象关联起来,以初始化这个虚拟存储器区域的内容,这个过程成为存储器映射。具体可以映射的对象有两种:

  • Unix文件系统中的普通文件。一个区域可以映射到一个普通磁盘文件的连续部分。
  • 匿名文件。匿名文件由内核创建,包含的全是二进制的0。

一旦一个虚拟页面被初始化了,它就在一个由内核维护的专门的交换文件之间换来换去。交换文件也叫交换空间,或交换区域。

共享对象

一个对象被映射到虚拟存储器的一个区域,要么作为共享对象,要么作为私有对象。

一个映射到共享对象的虚拟存储器区域叫做共享区域,类似的,也有虚拟区域。

私有对象时使用一种叫做写时拷贝的技术被映射到虚拟存储器中的,相应私有区域的页表条目都被标记为只读,并且区域结构被标记为私有的写时拷贝。

execve函数

使用execve函数将a.out程序加载到存储器的过程

Execve("a.out",NULL,NULL);

具体经过的步骤如下:

  • 删除已存在的用户区域。
  • 映射私有区域。
  • 映射共享区域。
  • 设置程序计数器。

    使用map函数的用户级存储器映射

Unix进程可以使用mmap函数来创建新的虚拟存储器区域,并将对象映射到这些区域当中

void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offest);
                        若成功则为指向映射区域的指针,若出错则为MAP_FAILDE(-1)

munmap函数删除虚拟存储器的区域。

int munmap(void *start,size_t length);
                        若成功则返回0,若失败则返回-1.

9.9 动态存储器分配

动态存储器分配器

当运行时需要额外虚拟存储器时,使用动态存储器分配器维护一个进程的虚拟存储器区域。分配器有两种风格。

  • 显示分配器:要求应用显式地释放任何已经分配的块。
  • 隐式分配器:要求分配器检测一个已分配块何时不再被程序所使用,就释放这个块。也叫做垃圾收集器。

malloc和free函数

C标准库提供了一个称为malloc程序包的显式分配器,程序通过调用malloc函数来从标准堆中分配块。

void *malloc(size_t size);
                若成功则为指针,若出错则为NULL。

通过调用free函数来释放已分配的块。

 void free(void *ptr);

分配器的目标和要求

显式分配器工作的约束条件:

  • 处理任意请求序列。
  • 立即响应请求。
  • 只使用堆。
  • 对齐块(对齐要求)。
  • 不修改已分配的额块。

理想分配器的目标:

  • 最大化吞吐率:吞吐率定义为每个单位时间里完成的请求数。
  • 最大化存储器利用率:最有用的标准是峰值利用率。

9.10 垃圾收集

垃圾收集器是一种动态存储分配器。,自动释放程序已经不再需要的已分配快(垃圾)。

垃圾收集器的基本知识

垃圾收集器将存储器视为一张有向可达图,图的节点被分配为一组根节点和一组堆节点。当存在一条从任意根节点出发到并到达P的有向路径时,就称节点P是可达的。

Mark&Sweep垃圾收集器

Mark&Sweep垃圾收集器由标记阶段和清除阶段组成,标记阶段标记出根节点所有可达的和已分配的后继,清除阶段释放每个未被标记的已分配块。

在对Mark&Sweep的描述中使用下列函数

  • ptr isPtr(ptr p):如果p指向一个已分配块中的某个字,那么就返回一个指向这个块起始位置的指针b,否则返回NULL。
  • int blockMarked(ptr b):如果已经标记了块b,就返回true。
  • int blockAllocated(ptr b):如果块b是已分配的,就返回true。
  • void markBlock(ptr b):标记块b。
  • int length(ptr b):返回块b的以字为单位的长度(不包括头部)。
  • void unmarkBlock(ptr b):将块b的状态由已标记的改为未标记的。
  • ptr nextBlock(ptr b):返回堆中块b的后继。

9.11 C语言中常见的与存储器有关的错误

  • 间接引用坏指针:在进程的虚拟地址空间中有较大的洞,没有映射到任何有意义的数据,如果试图引用一个指向这些洞的指针,操作系统就会以段异常来终止程序。典型的错误是:

    scanf("%d",val);

  • 读未初始化的存储器:虽然bass存储器位置总是被加载器初始化为0,但对于堆存储器却并不是这样的。
  • 允许栈缓冲区溢出:如果一个程序不检查输入串的大小就。写入栈中的目标缓冲区,程序就会出现缓冲区溢出错误。
  • 假设指针和指向他们的对象大小是相同的。
  • 造成错位错误。
  • 引用指针,而不是他所指向的对象。
  • 误解指针运算:忘记了指针的算术操作是以它们指向的对象的大小为单位来进行,而这种大小单位不一定是字节。
  • 引用不存在的变量。
  • 引用空闲堆块中的数据。
  • 引起存储器泄露:当不小心忘记释放已分配块,而在堆里创建了垃圾时,就会引起存储器泄露。
时间: 2024-10-13 00:23:42

12.7-12.13学习笔记的相关文章

《C++ Primer Plus》12.7 队列模拟 学习笔记

Heather银行打算在Food Heap超市开设一个自动柜员机(ATM).Food Heap超市的管理者担心排队使用ATM的人流会干扰超市的交通,希望限制排队等待的人数.Heather银行希望对顾客排队等待的事件进行估测.要编写一个程序来模拟这种情况,让超市的管理者可以了解ATM可能招骋的影响.对于这种问题,最自然的方法是使用顾客对列.队列是一种抽象的数据类型(Abstract Data Type,ADT),可以存储有序的项目序列.新项目被添加在队尾,并可以删除队首的项目.队列有点像栈,单栈在

2016.12.15网络编程学习笔记

---恢复内容开始--- TCP/IP协议族已经帮我们解决了这个问题,网络层的"ip地址"可以唯一标识网络中的主机,而传输层的"协议+端口"可以唯一标识主机中的应用程序(进程).利用三元组(ip地址,协议,端口)就可以标识网络的进程.TCP/IP协议的应用程序通常采用应用编程接口:UNIX  BSD的套接字(socket),来实现网络进程之间的通信,网络中进程通信是无处不在,这就是我为什么说"一切皆socket".socket起源于Unix,而U

2017/03/13学习笔记

cout<<标准输出cin>>标准输入定义一个类,是一个抽象概念,不会给你分配内存.用数据类型定义变量的时候,才会分配内存. C语言是在实践的过程中逐步完善起来的.没有深思熟虑的设计过程.使用时存在很多的"灰色地带"残留量过多低级语言的特征直接利用指针进行内存操作.C语言的目标是高效最终程序执行效率的高效C语言和C++并不是对立的竞争关系.C++ 是C语言的加强,是一种更好的C语言.C++ 是以C语言的为基础,并且完全兼容C语言的特性 C语言中无法取得regis

[原创]java WEB学习笔记12:一个简单的serlet连接数据库实验

本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 ---------------------------------

Java程序猿的JavaScript学习笔记(12——jQuery-扩展选择器)

计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript学习笔记(3--this/call/apply) Java程序猿的JavaScript学习笔记(4--this/闭包/getter/setter) Java程序猿的JavaScript学习笔记(5--prototype) Java程序猿的JavaScript学习笔记(6--面向对象模拟) Java程

python 学习笔记 12 -- 写一个脚本获取城市天气信息

最近在玩树莓派,前面写过一篇在树莓派上使用1602液晶显示屏,那么能够显示后最重要的就是显示什么的问题了.最容易想到的就是显示时间啊,CPU利用率啊,IP地址之类的.那么我觉得呢,如果能够显示当前时间.温度也是甚好的,作为一个桌面小时钟还是很精致的. 1. 目前有哪些工具 目前比较好用的应该是 weather-util, 之前我获取天气信息一般都是通过它. 使用起来也很简单: (1) Debian/Ubuntu 用户使用 sudo apt-get install weather-util 安装

《深入Java虚拟机学习笔记》- 第12章 整数运算

Java虚拟机提供几种进行整数算术运算的操作码,他们执行基于int和long类型的运算.当byte.short和char类型值参与算术运算时,首先会将它们转换为int类型.这些操作码都不会抛出异常,溢出在这里通常可以被忽略. 整数加法 操作码 操作数 说明 iadd (无) 从栈中弹出两个int类型数,相加,然后将所得int类型结果压回栈 ladd (无) 从栈中弹出两个long类型数,相加,然后将所得long类型结果压回栈 将一个常量与局部变量相加 操作码 操作数 说明 iinc vindex

【算法导论】学习笔记——第12章 二叉搜索树

搜索树数据结构支持多种动态集合操作,包括SEARCH.MINIMUM.MAXIMUM.PREDECESSOR.SUCCESSOR.INSRT和DELETE操作等.基本的搜索树就是一棵二叉搜索树.12.1 什么是二叉搜索树1. 二叉搜索树的性质:设x是二叉搜索树中的一个结点.如果y是x左子树中的一个结点,那么y.key<=x.key.如果y是x右子树中的一个结点,那么y.key>=x.key.三种遍历时间复杂度是O(n),这是显然的. 12.1-3 1 void Inorder_Tree_Wal

python基础教程_学习笔记12:充电时刻——模块

充电时刻--模块 python的标准安装包括一组模块,称为标准库. 模块 >>> import math >>> math.sin(0) 0.0 模块是程序 任何python程序都可以作为模块导入. $ cat hello.py #!/usr/bin/python print "Hello,signjing!" $ ./hello.py Hello,signjing! 假设将python程序保存在/home/ggz2/magiccube/mysh/p