读书笔记系列深入理解计算机系统之虚拟内存

前言

一个系统中的进程和其他进程共享cpu和主存资源,这样的内存很容易被破坏。为了更加有效的管理内存少出错,现代系统使用虚拟内存概念。

虚拟内存提供的作用

虚拟内存与物理地址关系 计算机系统主存被组织成一个由M个连续的字节大小组成的数组。每个字节有唯一的物理地址,cpu访问内存就是使用物理地址,称为物理寻址.早期PC使用这种方式,现代处理器使用的是虚拟寻址,即CPU通过生成一个虚拟地址,这个虚拟地址在送达内存之前先转换为适当的物理地址,这个过程叫做地址翻译

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

此处输入图片的描述

页表 同任何缓存一样,虚拟内存必须有某种方法判定一个虚拟页是否缓存在DRAM中某个地方。以及缓存时虚拟页存放的物理页中和不缓存时虚拟页存放物理地址,缓存替换牺牲页,页表将虚拟页映射到物理页

此处输入图片的描述

页命中 如果在通过PTE读取在虚拟内存时,直接通过PTE读取物理内存读取,如上图VP2,称为页命中

缺页 如果在通过PTE读取在虚拟内存时,发现数据并未缓存,则发生缺页,如上图VP3,该程序选择一个牺牲页,并且覆盖

分配页面 分配一个新的虚拟内存页时,如下图VP5在磁盘上创建空间并更新PTE5

此处输入图片的描述

整个运行过程中程序引用的不同页面总数可能会超过物理内存总的大小,局部性原则保证了在任意时刻,程序将区域在一个较小的活动页面集合上工作,这个集合叫做工作集。在初始开销,工作集页面会调度到内存中,接下来对工作集引用将导致命中。

操作系统为每个进程提供了一个独立的页表,因而也就是独立的虚拟地址空间。作为内存管理的工具,VM简化了链接和加载,代码和数据共享,以及应用程序的内存分配。并且保证了内存的安全,不允许一个进程修改它的制度代码,不允许它读或修改任何内核中代码和数据结构,不允许它读或者写其他进程的私有内存,不允许它修改任何与其他进程共享的虚拟页面。

此处输入图片的描述

多级页表

此处输入图片的描述

地址翻译

地址翻译必须和系统中所有硬件缓存的操作集成,大多数页表条目位于L1高速缓存,但是一个称为TLB的页表条目的片上高速缓存,通常会消除访问在L1上的页表条目开销。

内存映射 Linux通过虚拟内存区域与一个磁盘上对象关联起来,对象类型为:

进程间共享对象 此处输入图片的描述 此处输入图片的描述

动态内存分配

动态内存分配器维护着一个进程的虚拟内存区域,称为堆。分配器将堆是为一组不同大小的块的集合,每个块就是一个连续的虚拟内存片,要么已分配的,要么空闲的。已分配的显示保留为程序使用,空闲块用来被显式分配(C中malloc),已分配块保持已分配状态,直到被显式(C中free)或隐式释放(java的垃圾回收)。

碎片 堆利用率低的主要原因是碎片,虽然有未使用的内存但不能用来满足分配请求时,就会发生这种现象。

垃圾收集 垃圾收集器将内存视为一张有向可达图,由一个根节点和一组堆节点组成。当不存在一条从任意节点触发到达任意一个堆节点P的有向路径时,我们说P不可达,p会得到释放