操作系统导论——第13章 抽象:地址空间

一、早期系统

       从内存来看,早期的机器并没有提供多少抽象给用户。基本上,机器的物理内存如图13.1所示

        操作系统曾经是一组函数(实际上是一个库),在内存中(在本例中,从物理地址0开始),然后有一个正在运行的程序(进程),目前在物理内存中(在本例中,从物理地址64KB开始), 并使用剩余的内存。这里几乎没有抽象,用户对操作系统的要求也不多。

二、多道程序和时分共享

        由于机器昂贵,人们开始更有效地共享机器。因此,多道程序系统时代开启,其中多个进程在给定时间准备运行,比如当有一个进程在等待 I/O 操作的时候,操作系统会切换这些进程,从而增加了 CPU 的有效利用率

        但很快,分时系统的时代诞生了,许多人意识到批量计算的局限性,尤其是程序员本身,厌倦了长时间的(低效率的)编程——调试循环。交互性变得很重要,因为许多用户可能同时在使用机器,每个人都在等待(或希望)它们执行的任务及时响应。

        一种实现时分共享的方法,是让一个进程单独占用全部内存运行一小段时间(见图 13.1),然后停止它,并将它所有的状态信息保存在磁盘上(包含所有的物理内存),加载其他进程的状态信息,再运行一段时间,这就实现了某种比较粗糙的机器共享。 

        这种方法的问题:太慢,特别是当内存增长的时候。虽然保存和恢复寄存器级的状态信息(程序计数器、通用寄存器等)相对较快,但将全部的内存信息保存到磁盘就太慢了。因此,在进程切换的时候,我们仍然将进程信息放在内存中,这样操作系统可以更有效率地实现时分共享(见图13.2)。

        在图13.2中,有3个进程(A、B、C),每个进程拥有从 512KB 物理内存中切出来给它们的一小部分内存。假定只有一个CPU,操作系统选择运行其中一个进程(比如A),同时其他进程(B和C)则在队列中等待运行。 

       随着时分共享变得更流行,对操作系统又有了新的要求。特别是多个程序同时驻留在内存中,使保护(protection) 成为重要问题不希望一个进程可以读取其他进程的内存,更别说修改

三、地址空间

        操作系统需要提供一个易用的物理内存抽象。这个抽象叫做地址空间,是运行的程序看到的系统中的内存。理解这个基本的操作系统内存抽象,是了解内存虚拟化的关键。

         一个进程的地址空间包含运行的程序的所有内存状态。比如:程序的代码(code,指令) 必须在内存中,因此它们在地址空间里。当程序在运行的时候,利用(stack)来保存当前的函数调用信息分配空间给局部变量传递参数和函数返回值。最后,(heap)用于管理动态分配的、用户管理的内存,就像从C语言中调用 malloc() 或面向对象语言(如C ++ 或Java)中调用new 获得内存。当然,还有其他的东西(例如,静态初始化的变量),但现在假设只有这3个部分:代码、栈和堆

        在图 13.3 的例子中,有一个很小的地址空间(16KB)。程序代码位于地址空间的顶部(本例中从 0 开始,并且装入到地址空间的前 1KB)。代码是静态的(因此很容易放在内存中),所以可以将它放在地址空间的顶部,我们知道程序运行时不再需要新的空间。

        接下来,在程序运行时,地址空间有两个区域可能增长(或者收缩)。它们就是堆(在顶部) 和栈(在底部)。通过将它们放在地址空间的两端,可以允许这样的增长:它们只需要在相反的方向增长。因此堆在代码(1KB) 之下开始并向下增长(当用户通过 malloc()请求更多内存时),栈从 16KB 开始并向上增长(当用户进行程序调用时)。然而,堆栈和堆的这种放置方法只是一种约定,如果你愿意, 可以用不同的方式安排地址空间 [当多个线程(threads)在地址空间中共存时,就没有像这样分配空间的好办法了]。

        当然,描述地址空间时,所描述的是操作系统提供给运行程序的抽象。程序不在物理地址0~16KB的内存中,而是加载在任意的物理地址。回顾图13.2中的进程 A、B和C,可以看到每个进程如何加载到内存中的不同地址。因此问题来了:

                                                 关键问题:如何虚拟化内存

        操作系统如何在单一的物理内存上为多个运行的进程(所有进程共享内存)构建一个私有的、可能很大的地址空间的抽象?

        当操作系统这样做时,我们认为操作系统在虚拟化内存(virtualizing memory),因为运行的程序认为它被加载到特定地址(例如 0)的内存中,并且具有非常大的地址空间(例如 32 位或64位)。现实很不一样。

        例如,当图13.2中的 进程A 尝试在地址0(我们将称其为虚拟地址,virtual address) 执行加载操作时,然而操作系统在硬件的支持下,出于某种原因,必须确保不是加载到物理地址0,而是物理地址320KB(这是A载入内存的地址)。这是内存虚拟化的关键,这是世界上每一个现代计算机系统的基础。

四、目标

        操作系统的工作——虚拟化内存。操作系统不仅虚拟化内存,还有一定的风格。为了确保操作系统这样做,我们需要一些目标来指导。

         虚拟内存(VM)系统的一个主要目标透明(transparency)。操作系统实现虚拟内存的方式,应该让运行的程序看不见。因此,程序不应该感知到内存被虚拟化的事实,相反,程序的行为就好像它拥有自己的私有物理内存。在幕后,操作系统(和硬件)完成了 所有的工作,让不同的工作复用内存,从而实现这个假象。

         虚拟内存的另一个目标是效率(efficiency)。操作系统应该追求虚拟化尽可能高效 ,包括时间上(即不会使程序运行得更慢)和空间上(即不需要太多额外的内存来支持虚拟化)。在实现高效率虚拟化时,操作系统将不得不依靠硬件支持,包括TLB这样的硬件功能。

         虚拟内存第三个目标是保护(protection)。操作系统应确保进程受到保护(protect), 不会受其他进程影响,操作系统本身也不会受进程影响。当一个进程执行加载、存储或指令提取时,它不应该以任何方式访问或影响任何其他进程或操作系统本身的内存内容(即在它的地址空间之外的任何内容)。因此,保护让我们能够在进程之间提供隔离(isolation) 的特性,每个进程都应该在自己的独立环境中运行,避免其他出错或恶意进程的影响。

        在接下来的章节中,我们将重点介绍虚拟化内存所需的基本机制(mechanism),包括硬件和操作系统的支持。我们还将研究一些较相关的策略(policy),你会在操作系统中遇到它们,包括如何管理可用空间,以及在空间不足时哪些页面该释放。通过这些内容,你 会逐渐理解现代虚拟内存系统真正的工作原理①。

五、小结

        介绍了操作系统的一个重要子系统:虚拟内存。虚拟内存系统负责为程序提供一 个巨大的、稀疏的、私有的地址空间的假象,其中保存了程序的所有指令和数据。操作系统在专门硬件的帮助下,通过每一个虚拟内存的索引,将其转换为物理地址,物理内存根据获得的物理地址去获取所需的信息。操作系统会同时对许多进程执行此操作,并且确保程序之间互相不会受到影响,也不会影响操作系统。整个方法需要大量的机制(很多底层机制)和一些关键的策略。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39169.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络爬虫-2:基础与理论

一.同步加载与异步加载 1.1同步加载定义: 页面所有内容一起加载出来,当某一个数据加载有问题,整个页面就不会加载出来(如HiFiNi音乐网站),所以又叫阻塞模式 1.2爬取步骤: 看netword->document 2.1异步加载定义: 数据是分开加载的,当某一份数据有异常时,不影响其他数据…

【Docker系列五】Docker Compose 简介

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

本地安装deepseek大模型,并使用 python 调用

首先进入 ollama 官网 https://ollama.com/点击下载 下载完成后所有都是下一步,就可以 点击搜索 Models : https://ollama.com/search然后点击下载: 选择后复制: ollama run deepseek-r1:32b例如: 让它安装完成后&#xff1…

【CC2530 教程 二】CC2530定时器实现微秒、毫秒、秒延时函数

目录 一、CC2530定时器: 二、CC2530定时器: (1)定时器1(Timer1): (2)定时器2(Timer2): (3)定时器3和定时…

23种设计模式-创建型模式-工厂方法

文章目录 简介场景问题1. 直接依赖具体实现2. 违反开闭原则3. 条件分支泛滥4. 代码重复风险 解决根本问题完整类图完整代码说明核心优势代码优化静态配置表动态策略 总结 简介 工厂方法是一种创建型设计模式,它提供了在父类中创建对象的接口,但允许子类…

Umi-OCR- OCR 文字识别工具,支持截图、批量图片排版解析

Umi-OCR 是免费开源的离线 OCR 文字识别软件。无需联网,解压即用,支持截图、批量图片、PDF 扫描件的文字识别,能识别数学公式、二维码,可生成双层可搜索 PDF。内置多语言识别库,界面支持多语言切换,提供命令…

【JavaEE】Mybatis基础使用注解 增删改查操作

目录 一、配置日志二、传递参数 #{}三、增(Insert)四、返回主键Options五、删(Delete)六、改(Update)七、查(Select) 一、配置日志 我们加上下面的代码在配置文件中,那么我们在日志中就可以看到…

4.2、网络安全体系与建设内容

目录 网络安全体系架构网络安全组织安全管理网络安全等级保护2.0等保项目流程等保标准变化等保2.0新增内容等保2.0变化智慧城市安全体系应用参考智能交通网络安全体系应用参考 网络安全体系架构 建设网络安全,要体系化,要从一个整体去做考虑&#xff0c…

TCP协议原理

TCP协议原理 本篇介绍 前面已经基本介绍了TCP编程的接口以及基本的步骤,但是并没有其中的原理进行解释。本篇主要聚焦于TCP原理部分,对TCP中重要的内容进行解释 TCP协议报格式 基本示意图如下: 下面针对每一个字段的作用进行简要的概括&a…

go中的文件、目录的操作

1.文件的概念 文件是数据源(保存数据的地方)的一种,比如大家经常使用的word文档,txt文件,excel文件等。文件最主要的作用就是保存数据,它既可以保存一张图片,也可以保存视频,声音等。 文件在程序中以流的形式来操作的。 流:数据在数据源(文件)和程序(内存)之间…

electron js node vscode 调试electron

用npm会下到home里面不知道为什么可能是淘宝源的问题 --------------------------------- 安装cnpm(可选) sudo npm install -g cnpm --registryhttps://registry.npmmirror.com下下来还没办法直接用 sudo find / -name "cnpm"nano ~/.bashr…

深度解析 BPaaS:架构、原则与研发模式探索

在当今复杂多变的业务环境下,软件开发面临着诸多挑战,如何有效地管理业务复杂性并实现系统的可扩展性成为关键。BPaaS应运而生,它作为一种创新的理念和架构模式,改变着企业研发的方式。本文将深入探讨 BPaaS 是什么,以…

大模型架构记录2 【综述-相关代码】

一 简单聊天机器人搭建 1.1 openai调用 import os from openai import OpenAI from dotenv import load_dotenv, find_dotenvload_dotenv() client OpenAI()# 打印所支持的模型 model_lst client.models.list()for model in model_lst:print (model.id)# 调用API接口 comp…

三个print优雅打印datetime模块的“时间密码”

三个模块&三条print(),玩转python时间的上上下下,优雅打印“时间密码”。 笔记模板由python脚本于2025-03-23 22:50:43创建,本篇笔记适合正确研究时间/日期的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值:在于输出…

【Android】VehiclePropertyAccess引起CarService崩溃

VehiclePropertyAccess引起CarService崩溃 VehiclePropertyAccess VehiclePropertyAccess属性,用于定义车辆属性的访问权限。权限包括 读:READ,只可以读取,不能写入。 VehiclePropertyAccess:READ写:WRITE&#xf…

深入理解traceroute命令及其原理

traceroute 是一个网络诊断工具(Windows上叫tracert),用于显示数据包从本地主机到远程主机经过的路由(跳数)。它可以帮助您了解数据包在网络中的传输路径,以及每跳的延迟情况。这对于网络故障排除、分析网络…

Playwright + MCP:用AI对话重新定义浏览器自动化,效率提升300%!

一、引言:自动化测试的“瓶颈”与MCP的革新 传统自动化测试依赖开发者手动编写脚本,不仅耗时且容易因页面动态变化失效。例如,一个简单的登录流程可能需要开发者手动定位元素、处理等待逻辑,甚至反复调试超时问题。而MCP&#xf…

JVM 学习前置知识

JVM 学习前置知识 Java 开发环境层次结构解析 下图展示了 Java 开发环境的层级关系及其核心组件,从底层操作系统到上层开发工具,逐步构建完整的开发与运行环境: 1. 操作系统(Windows, MacOS, Linux, Solaris) 作用&…

【Java/数据结构】队列(Quque)

本博客将介绍队列的相关知识,包括基于数组的普通队列,基于链表的普通队列,基于数组的双端队列,基于链表的双端队列,但不包括优先级队列(PriorityQueue),此数据结构将单独发一篇博客&…

深度学习Python编程:从入门到工程实践

第一章 Python语言概述与生态体系 1.3 Python在工业界的应用场景 # 示例:使用FastAPI构建RESTful接口 from fastapi import FastAPI from pydantic import BaseModelapp = FastAPI()class Item(BaseModel):name: strprice: float@app.post("/items/") async def cr…