首页 > 其他 > 详细

第九章 虚拟内存

时间:2019-01-13 12:08:54      阅读:158      评论:0      收藏:0      [点我收藏+]

物理地址和虚拟地址:

计算机的主存被组织成一个由M个连续的字节大小的单元组成的数组。每个字节都有一个唯一的物理地址(PA)。第一个字节地址为0,接下来为1,再接下来为2,依次类推。CPU访问内存的最自然方式就是使用物理地址。我们把这种方式称为物理寻址。如图所示。

 

                                                                                                    技术分享图片

 

 现代处理器使用一种称为虚拟地址的寻址方式。使用虚拟寻址,CPU通过生成一个虚拟地址(VA)来访问主存,这个虚拟地址在被送到内存之前先准换成适当的物理地址。将一个虚拟地址转换成物理地址的任务叫做地址翻译。CPU上通过内存管理单元这个专用硬件,利用存放在主存中的查询表来动态翻译虚拟地址,该表的内容由操作系统管理。

 

                                                                                技术分享图片

 

 

地址空间

地址空间是一个非负整数地址的有序集合。如果地址空间中的整数是连续的,那么我们说它是一个线性的地址空间。在一个带虚拟内存的系统中,CPU从一个有N=2^n 个地址的地址空间中生成虚拟地址,这个地址空间称为虚拟地址空间。一个地址空间的大小由表示最大地址所需要的位数来描述。例如一个N=2^n 个地址的虚拟地址空间就叫做一个n位地址空间,现代操作系统通常支持32位和64位虚拟地址空间。

 

虚拟内存作为缓存的工具

概念上而言,虚拟内存被组织为一个由存放在磁盘上的N个连续的字节大小的单元组成的数组。每个字节都有唯一的虚拟地址,作为数组的索引。磁盘上数组的内容被缓存在主存中。和存储器层次结构中其他缓存一样,磁盘上(较低层)的数据被分割成块,这些块作为磁盘和主存(较高层)之间的传输单元。VM系统通过将虚拟内存分割成为虚拟页(Virtual Page,VP),每个虚拟页的大小为P = 2^p字节。类似的物理内存也被分割成为物理页(Physical Page,PP),大小也是P字节(物理页也被成为页帧)

在任意时刻,虚拟页面的集合都分为三个不相交的子集:

1、未分配的:VM系统还未分配(或者创建)的页。未分配的块没有任何数据和它们相互关联,因此也不占用任何磁盘空间。

2、缓存的:当前已缓存在物理内存中已分配的页

3、未缓存:未缓存在物理内存中的已分配页

 

                                                                                 技术分享图片

 

 

 

垃圾收集

在诸如C malloc包这样的显示分配器中,应用通过调用malloc和free来分配和释放堆块。应用要负责释放所有不再需要的已分配块。

未能释放已分配的块是一种常见的编程错误。

垃圾收集器是一种动态内存分配器,它自动释放程序不再需要的已分配块。这些块被称为垃圾。自动回收堆存储的过程叫做垃圾收集。

垃圾收集器可以将内存视为一张有向可达图,该图的节点被分为一组根节点和一组堆节点,每个堆节点对应于堆中的一个已分配块。根节点对应于这样一种不在堆中的位置,它们中包含指向堆中的指针。这些位置可以是寄存器、栈里的变量、或者是虚拟内存中读写数据区域内的全局变量。

当存在一条从任意根节点出发并到达p的有向路径时,我们可以说节点p是可达的。在任何时刻,不可达节点对应于垃圾,是不能被应用再次使用的。垃圾收集器的角色是维护可达图的某种表示,并通过释放不可达节点且将它们返回给空闲链表,来定期回收它们。

 

Mark&Sweep垃圾收集器

MarkSweep垃圾收集器由标记阶段和清除阶段组成,标记阶段标记出根节点的所有可达的和已分配的后继,而后面的清除阶段释放每个未被标记的已分配块。块头部中空闲的低位中的一位通常用来表示这个块是否被标记。

假设初始情况下,一个堆由六个已分配块组成,其中每个块都是未分配的。第三个块包含一个指向第一个块的指针。第四个块包含指向第三个块和第六个块的指针。根指向第四个块,在标记阶段之后,第一个快、第三个块、第四个块和第六个块都做了标记,因为它们是从根节点可达的。第二块和第五块是未标记的,因为它们是不可达的。在清除节点之后,这两个不可达块被回收到空闲链表。

 

C程序中常见的与内存相关的错误

对于C程序员来说,管理和使用虚拟内存是一件困难和容易出错的任务。常见的错误示例包括:间接引用坏指针,读取未初始化的内存,允许栈缓冲区溢出。假设指针和它们指向的对象大小相同,引用指针而不是它所指向的对象,误解指针运算,引用不存在的变量以及引起内存泄漏。

 

第九章 虚拟内存

原文:https://www.cnblogs.com/sunnyDream/p/10262138.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!