分段

基本方法

分段就是基于用户视图的内存管理方案。逻辑地址空间是由一组段构成的,每个段都有名称和长度。地址指定了段名称和段内偏移。因此用户通过两个量来指定地址:段名称段偏移

为了简单,进行对段的编号,是通过段号而不是段名称来引用的,所以逻辑地址由有序对组成:<段号,偏移>。

分段硬件

用户是通过二位地址来引用程序内的对象的,但是实际物理内存仍然是一维的字节序列。所以我们需要定义一个实现方式,用来映射用户定义的二维地址到一维的物理地址。这个地址是通过段表来实现的。段表的每个条目都有段基地址和段界限。段基地址包含该段在内存中的开始物理地址,段界限指定该段的长度。



段表的使用如上图所示,每个逻辑地址由两部分组成:段号s和段偏移d。段号用作段表的索引,逻辑地址的偏移d应位于0和段界限之间。如果不是这样,那么会陷入操作系统中(逻辑地址试图访问段的外面);如果d合法,那么就与基地址相加而得到所需字节的物理内存地址。因此,段表实际上是基址寄存器值和界限寄存器值的对的数组。

分页

分段允许进程德尔物理地址空间是非连续的。分页是提供这种优势的另一种内存管理方案,使用分页可以避免外部碎片和紧缩。

基本方法

实现分页的基本方法涉及将物理内存分为固定大小的块,称为页帧;而将逻辑内存也分为同样大小的块,称为页面。当执行一个进程时,它的页从文件系统或备份存储等源处,加载到内存的可用帧。备份存储划分为固定大小的块,它与单个内存帧或与多个内存帧(簇)的大小一样。

分页的硬件如下图所示,由CPU生成的每个地址分为两部分:页码§和页偏移(d)。页码作为页表的索引。页表包含每页所在的物理内存的基地址。这个基地址和页偏移的组合就是物理内存的内存地址,可发送到物理单元。



页大小是由硬件决定的。页的大小为2的幂,如果逻辑地址空间为2m2^m2m,且页大小为2n2^n2n字节,那么逻辑地址的高m-n位表示页码,而低n位表示页偏移。



其中p为页表的索引,d为页的偏移。

采用分页方案不会产生外部碎片:每个空闲帧都可以分配给需要他的进程,但是,分页有内部碎片。分页是以帧为单位进行的,如果进程所要求的内存并不是页的整数倍,那么最后一个帧就用不完。如果进程大小与页大小无关,那么每个进程的内部碎片的均值为半页。

硬件支持

页表的硬件实现有多种方法,最简单的一种方法就是:将页表作为一组专用的寄存器来实现。这些寄存器应用告诉逻辑电路来构造,以高效的进行分页地址的转换。CPU分派器在加载其他寄存器的时候,也需要加载这些寄存器。注意,这种方法适用于页表比较小的情况下。

大多数的现代计算机都允许页表非常大,对于这种情况,需要将页表放在内存中,并将页表基址寄存器指向页表。改变页表只需要改变这一寄存器就行了。注意,如果采用这种方法,访问一个字节需要两次访问内存(一次用于页表条目,一次用于字节)。

标准方法是:采用转换表缓冲区(TLB),TLB是关联的高速内存,TLB条目是由两部分组成:键(标签)和值。当关联内存根据给定值查找时,它会同时与所有的键进行比较。如果找到条目,就得到相应值的字段。

TLB和页表一起使用的方法是:TLB只包含少数的页表条目。当CPU产生一个逻辑地址后,它的页码就发送到TLB。如果找到这个页码,它的帧码就立即可用,可用基于访问内存。如果页码不在TLB中,也就是TLB未命中。那么就需要访问页表。有的TLB在每个TLB条目中还保存地址空间标识符(ASID),ASID唯一标识每个进程,并为进程提供地址空间的保护。

保护

分页情况下的内存保护是通过与每个帧关联的保护位来实现的。用一个位可以定义一个页是可读可写的还是只可读。每次内存引用都要通过页表,来查找正确的帧码。在计算物理地址的同时,可以通过检查保护位来验证与没有对只读页进行操作。

还有一个位通常与页表中的每一条目相关联:有效-无效位。当该位为有效时,该值表示相关的页在进程的逻辑地址空间内,因此是合法的页。当该位是无效的时候,该值表示先关的页不在进程的逻辑地址空间内。通过使用有效-无效位,非法地址会被捕捉到。

还有一个问题,一个进程很少会使用的它的所有地址空间,如果为地址范围内的所有页都在页表中建立一个条目,这将是非常浪费的。有的系统会提供硬件来解决这个问题,如**页表长度寄存器(PTLR)**来表示页表的大小,该寄存器的值可用于检查每个逻辑地址以验证其是否位于进程的有效范围内。

共享页

分页的优点之一就是可以共享公共代码。

注意:代码必须是可重入代码纯代码才可以共享。可重入代码是不能自我修改的代码,他在执行期间不会改变

页表结构

分层分页

现代操作系统支持大逻辑地址空间,在这种情况下页表本身可以非常的大。比如一个位逻辑地址空间的计算机操作系统。如果系统的页大小为4KB(2122^{12}212),那么页表可以多达100万的条目,假设每个条目有4字节,那么每个进程需要4MB物理地址空间来存储页表本身。

常用的解决方法就是分层分页。比如两层分页算法,就是将页表在分页。



其中p1p_1p1​是用来访问外部页表的索引,p2p_2p2​是内部页表的页偏移,这种方案一般称为向前映射页表

对于64位的架构,分层分页是不适用的,因为每一层的页表分完之后还是太大了。

哈希页表

处理大于32位地址空间的常用方法就是使用哈希页表。采用虚拟页码作为哈希值。哈希页表的每一个条目都包括一个链表,该链表的元素哈希到同一位置(该链表用来解决碰撞)。每个元素由三个字段组成:

  1. 虚拟页码
  2. 映射的帧码
  3. 指向链表内下一个元素的指针

该算法的工作:虚拟地址的虚拟页码哈希到哈希表。用虚拟页码与链表内的第一个元素的第一个字段相匹配。如果匹配,那么相应的帧码就用来形成物理地址;如果不匹配,那么与链表内的后续节点的第一个字段进行比较,以查找匹配的页码。

基于哈希页表的一个变体采用聚簇页表,哈希表中的每个条目引用多个页而不是单个页,因此单个页表条目可以映射到多个物理帧。聚簇页表对于稀疏地址空间特别有用,这里的引用是不连续的并且散步在整个地址空间中。

倒置页表

通常情况下每个进程都有一个页表,该进程使用的每个页都是该页表的一项。但是这种方法的缺点就是会造成每个页表可能包含数以百万记的条目,占用大量的内存。

所以有了倒置页表。对于每个真正的内存页或帧,倒置页表才有一个条目。每个条目包含保存在真正内存位置上的页的虚拟地址以及拥有该页进程的信息。所以在一个系统中只有一个页表,并且每物理内存的页只有一条相应的条目。

由于一倒置页表通常包含多个不同的映射物理内存的地址空间,通常要求它的每个条目保存一个地址空间标识符,用来确保具体进程的每个逻辑页可映射道德相应的物理帧。

参考:《操作系统概念》(第九版)

OS之内存管理 ---基本的内存管理策略(二)的更多相关文章

  1. OS之内存管理 ---基本的内存管理策略(一)

    基本概念 基本硬件 CPU可以直接访问的通用存储只有内存和处理器的内置的寄存器.机器指令可以用内存地址作为参数,而不能用磁盘地址作为参数.所以执行指令以及指令使用的数据,应在这些可执行访问的存储设备上 ...

  2. 【uTenux实验】内存池管理(固定内存池和可变内存池)

    1.固定内存池管理实验 内存管理是操作系统的一个基础功能.uTenux的内存池管理函数提供了基于软件的内存池管理和内存块分配管理.uTenux的内存池有固定大小的内存池和大小可变的内存池之分,它们被看 ...

  3. 转:内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[C++][内存管理][转载]

    内存区划分.内存分配.常量存储区.堆.栈.自由存储区.全局区[C++][内存管理][转载] 一. 在c中分为这几个存储区1.栈 - 由编译器自动分配释放2.堆 - 一般由程序员分配释放,若程序员不释放 ...

  4. (转)从内存管 理、内存泄漏、内存回收探讨C++内存管理

    http://www.cr173.com/html/18898_all.html 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟 ...

  5. 5. c++ 内存管理 C/C++ 内存机制

    参考自:http://blog.csdn.net/wpf_ml/article/details/7759911 1. 内存,Cache,寄存器内存:通常计算机将数据存放在物理内存,cache及寄存器中 ...

  6. Java内存管理:Java内存区域 JVM运行时数据区

    转自:https://blog.csdn.net/tjiyu/article/details/53915869 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些, ...

  7. Linux-内存管理机制、内存监控、buffer/cache异同

    在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然.这是Linux内存管理的一个优秀特性,主要特点是,无论物理内存有多大,Linux 都将其充份利用,将 ...

  8. 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配

    垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己 ...

  9. Windows内存管理和linux内存管理

    windows内存管理 windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或 ...

  10. 内存管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现

    http://blog.csdn.net/pi9nc/article/details/23334659 注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料 ...

随机推荐

  1. 2018.09.15 poj2117Electricity(割点)

    传送门 其实求一个图删除一个点之后,联通块最多有多少. 直接tarjan求割点更新答案就行了. 但注意原图不一定连通. 代码: #include<iostream> #include< ...

  2. yii2 HTML组手

    1.样式和脚本 1.1 Yii 提供两个方法用于生成包含内联样式和脚本代码的标签. <?= Html::style('.danger { color: #f00; }') ?> Gives ...

  3. MySQL 的IFNULL()、ISNULL()和NULLIF()函数

    参考与http://blog.csdn.net/xingyu0806/article/details/52080962 IFNULL(expr1,expr2) 假如expr1不为NULL,则 IFNU ...

  4. Axios的基本使用

    Axios的基本使用 介绍 Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中.在vue 中,用来发ajax请求,与后端交互. 从浏览器中创建 XMLHtt ...

  5. UVa 11992 Fast Matrix Operations (线段树,区间修改)

    题意:给出一个row*col的全0矩阵,有三种操作 1 x1 y1 x2 y2 v:将x1 <= row <= x2, y1 <= col <= y2里面的点全部增加v: 2 ...

  6. gorename: easy refactoring tool for Golang[转]

    To inaugurate this attempt of blog, I’ll talk about gorename a small but incredibly useful tool I ju ...

  7. [转自知乎] 从github上下载单个文件夹

    原文地址: 如何从 GitHub 上下载单个文件夹?  注意:如果是在公司网络环境的话需要配置可以访问外网的代理,否则 svn checkout 时会出错.

  8. 网页程序 vs 桌面程序

    网页程序 vs 桌面程序 阅读:  评论:  作者:Rybby  日期:  来源:rybby.com 所谓的网页程序就是指以网页作为程序的操作界面,通过脚本语言“javascript”或其它客户端语言 ...

  9. Ansible配置文件

    官方配置文件文档 Ansible安装完成之后默认配置文件为:/etc/asnible/ansible.cfg Ansible配置文件内容: cat ansible.cfg # config file ...

  10. Android Sms短信发送

    界面布局: 具体代码: private void sendSms() { // 获取电话号码和短信内容 String number = number1.getText().toString(); St ...