【操作系统导论】内存篇——分段

news2024/12/28 3:32:30

引入

利用基址和界限寄存器,操作系统很容易将不同进程重定位到不同的物理内存区域。

但是,对于一整个地址空间,在栈和堆之间存在一块空闲空间,如果将整个地址空间分配给进程,无疑造成了大量的内存浪费。

为了解决这个问题,分段 (segmentation) 的概念应运而生。

在典型的地址空间里划分 3 个段:代码段、栈段、堆段;为每个段配置一对基址界限寄存器。

分段机制使得 OS 能够将不同的段放到不同的物理内存区域,从而避免地址空间中的未使用部分占用实际物理内存。

分段机制

标识不同段

硬件在地址转换时,如何知道段内的偏移量,以及地址引用了哪个段(基址)?

**显式 (explicit) 方式:**用虚拟地址的开头几位来标识不同的段。

举例,假设地址空间划分为 3 个段,则可以用 14 位虚拟地址的前两位来标识,如下所示:

在这里插入图片描述

用虚拟地址的后 12 位作为段内偏移,与基址寄存器相加,就得到了最终的物理地址。

并且,偏移量简化了对段边界的判断:检查偏移量是否小于界限,大于界限的为非法地址。

**隐式 (implicit) 方式:**硬件通过地址产生的方式来确定段。

举例,类似段寄存器CS、DS、SS:

  • 对于数据段,将它的段地址放在 DS 中;

  • 对于代码段,将它的段地址放在 CS 中;

  • 对于栈段,则将它的段地址放在 SS 中;

栈反向增长

需要注意的是,在虚拟内存和物理内存中,栈都是反向增长的。

在这里插入图片描述

因此,在进行地址转换时,计算方式有所不同:

假设要访问虚拟地址 15KB,对应二进制 11 1100 0000 0000,前 2 位标识栈段,后 12 位为偏移量 3KB;并假设段的大小为 4KB。

  • 反向偏移量 = 3KB - 4KB = −1KB。

  • 物理地址 = 反向偏移量 + 基址 = -1KB + 28KB = 27KB

用户可以进行界限检查,确保反向偏移量的绝对值小于段的大小。

代码段共享

随着分段机制不断改进,系统设计人员意识到,在地址空间之间共享某些内存段(代码段), 可以节省内存空间,提升效率。

为了支持共享,需要一些额外的硬件支持,这就是 保护位(protection bit)

  • 为每个段增加了几个位,来标识程序对该段的访问权限,即:读、写、执行;

  • 如果将代码段标记为「读-执行」,则代码可以被多个进程共享,而不用担心破坏隔离。

在这里插入图片描述

问题分析

第一个是老问题:操作系统在上下文切换时应该做什么?

各个段寄存器中的内容必须保存和恢复。

每个进程都有自己的虚拟地址空间,OS 必须在进程运行前,确保这些寄存器被正确地赋值。

第二个问题:操作系统如何管理物理内存中的空闲空间?

在动态内存分配和释放的过程中,分配和释放的内存段不总是处于连续的位置,导致内存中出现许多零散的空闲内存,这些零散的内存不足以满足某个特定大小的内存请求,从而导致内存空间的浪费,这类问题被称为 外部碎片 (external fragmentation) 问题

一种解决方案是:紧凑 (compact) 物理内存,重新安排原有的段。

但是,内存紧凑成本很高,因为拷贝段是内存密集型的,一般会占用大量的处理器时间。

另一种解决方案:利用空闲列表管理算法,试图保留大的内存块用于分配。

相关算法有几百上千种,包括:最优匹配、最坏匹配、首次匹配、伙伴算法;

遗憾的是,无论算法多么精妙,都无法完全消除外部碎片,因此,好的算法只是试图减小它。

空闲列表

在堆上管理空闲空间 的数据结构通常称为 空闲列表(free list)

该结构包含了管理内存区域中所有空闲块的引用;空闲列表不一定真的是列表,只是某种可以追踪空闲空间的数据结构。

分割与合并

空闲列表包含一组元素,记录了堆中的哪些空间还没有分配。假设有下面的 30 字节的堆:

在这里插入图片描述

这个堆对应的空闲列表会有两个元素:

在这里插入图片描述

显然,大于 10 字节的分配请求会失败(返回 NULL);而恰好 10 字节的需求可以由两个空闲块中的任何一个满足。

但是,如果申请小于 10 字节空间,会发生什么?

假设申请了一个字节的内存,分配程序会执行 **分割(splitting)**操作:

找到一块可以满足请求的空闲空间,将其分割,第一块返回给用户,第二块留在空闲列表中。

可能得到以下结果:

在这里插入图片描述

如果应用程序调用 free(10),归还堆中间的空间,会发生什么?

在释放一块内存时,分配程序会 **合并(coalescing)**可用空间:

如果待归还的内存块存在着相邻的空闲内存块,则将它们合并为一个较大的空闲内存块。

通过合并,空闲列表会回到其最初的样子:

在这里插入图片描述

释放内存块

free(void *ptr) 没有块大小的参数,它如何确定待释放空间的大小呢?

大多数分配程序会在 **头块(header)**中记录额外的信息,头块的定义如下:

typedef struct header_t 
{ 
    int size;     // 分配空间的大小
    int magic;    // 幻数, 用于检验完整性
} header_t;

可想而知,用户在调用 free(void *ptr) 时,内存分配库会通过简单的指针运算得到头块的位置:

void free(void* ptr) 
{ 
    header_t* hptr = (void *)ptr - sizeof(header_t); 
}

在这里插入图片描述

获得头块指针后,内存分配库通过幻数进行正常性检查 assert(hptr->magic == 1234567);

并计算待释放空间的大小,即 头块大小 + 分配给用户的空间的大小

代码实现

现在,我们已经了解了空闲列表的概念,接着,我们用代码实现它!

typedef struct node_t 
{ 
    int size;                // 空闲节点的大小
    struct node_t *next;     // 指向下一个节点
} node_t;

下面来初始化「堆」,假设「堆」的大小为 4096 字节,将空闲列表的第一个元素放在该空间中:

// mmap() returns a pointer to a chunk of free space 
node_t* head = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); 
head->size = 4096 - sizeof(node_t); 
head->next = NULL;

如何,假设有一个 100 字节的内存请求,则空闲列表会有以下变化:

在这里插入图片描述

再来看下面的一个例子,应用程序调用 free(16500);,归还了中间的一块已分配空间:

在这里插入图片描述

基本策略

上面介绍了空闲列表的底层机制,现在来介绍一些 空闲分区算法

最佳适应

遍历空闲列表,选择最接近用户请求大小的空闲块,即 优先使用小空间,尽量避免空间浪费

可以将空闲分区按容量递增次序链接,每次分配内存时顺序查找空闲列表,找到大小能满足的第一个空闲分区。

最坏适应

遍历空闲列表,选择最大的空闲块,分割并满足用户需求后,将剩余的块加入空闲列表

可以将空闲分区按容量递减次序链接,每次分配内存时顺序查找空闲列表,找到大小能满足要求的第一个空闲分区。

首次适应

每次从 低地址 开始查找,找到第一个能满足用户请求大小的空闲分区。

可以将空闲分区按容量递增次序链接,每次分配内存时顺序查找空闲列表,找到大小能满足的第一个空闲分区。

邻近适应

额外维护一个指针,指向上一次查找结束的位置;

每次从上次查找结束的位置开始检索,找到第一个能满足用户请求大小的空闲分区。

简单总结:

  • 最佳适应算法和最坏适应算法的开销较大。

  • 首次适应算法和邻近适应算法的开销较小;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试面试八股文(答案解析+视频教程)

1、B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行,可以实现跨平台,客户端零维护,维护成本低,但是个性化能力低,响应速度较慢。 C/S响应速度快,安全性强,一般应用于局域网中&#xf…

场景化文案怎么来的?媒介盒子拆解写作技巧

为什么有时候你的软文营销起不到作用、用户不买单?可能是引起你没有做好场景提醒,没有切中用户的切身利益点。今天媒介盒子就来和大家聊聊:场景化文案怎么写。 一、 场景文案核心点 在了解场景化文案的写作技巧前,咱们先来理清场…

如何将3dMax重置为默认的“出厂”设置?

如何将3dMax重置为“出厂”设置? 我们在使用3dMax软件时,有时会遇到一些问题,比如:启动时或使用程序内的特定功能时崩溃;3dMax界面显示问题;视口操纵缓慢或不稳定;键盘快捷方式丢失;…

Re9 Attention is all you need

变形金刚,启动! Abstract 主流序列转录模型基于复杂的循环神经网络和卷积神经网络,包括一个encoder和decoder,同时在这之中使用一个叫注意力机制attention的东西本文提出了一个简单的网络架构,仅仅使用注意力机制&am…

0基础学java-day19(IO流)

一、文件 1 什么是文件 2.文件流 3.常用的文件操作 3.1 创建文件对象相关构造器和方法 package com.hspedu.file;import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test;import java.io.File; import java.io.IOException;/*** author 林然* vers…

多模态融合slam技术学习

目录 前言 一、视觉-惯性SLAM算法 二、激光-惯性SLAM算法 三、激光与视觉融合算法 总结 前言 最近在找实习,又想着要怎么完成毕业论文,打算做下机器人导航实验,学习下相关算法。今天是多模态融合slam技术,课程链接:h…

严世芸龟法养生经

文章目录 严世芸理念荤素搭配,不偏嗜动静结合心平气和 龟息法 严世芸 严世芸,出生于1940年,现任上海中医药大学的主任医师,教授。他父亲是近代上海有名的中医,他又是著名医家张伯臾的亲传弟子。 从小就在父亲诊室里长…

ArkTS入门

代码结构分析 struct Index{ } 「自定义组件:可复用的UI单元」 xxx 「装饰器:用来装饰类结构、方法、变量」 Entry 标记当前组件是入口组件(该组件可被独立访问,通俗来讲:它自己就是一个页面)Component 用…

排序算法:【冒泡排序】、逻辑运算符not用法、解释if not tag:

注意: 1、排序:将一组无序序列,调整为有序的序列。所谓有序,就是说,要么升序要么降序。 2、列表排序:将无序列表变成有序列表。 3、列表这个类里,内置排序方法:sort( )&#xff0…

喜报丨迪捷软件入选2023年浙江省信息技术应用创新典型案例

12月6日,浙江省经信厅公示了2023年浙江省信息技术应用创新典型案例入围名单。本次案例征集活动,由浙江省经信厅、省密码管理局、工业和信息化部网络安全产业发展中心联合组织开展,共遴选出24个优秀典型解决方案,迪捷软件“基于全数…

Matlab示例-Examine 16-QAM Using MATLAB学习笔记

​工作之余学习16-QAM 写在前面 网上看到许多示例,但一般都比较难以跑通。所以,还是老方法,先将matlab自带的例子研究下。 Examine 16-QAM Using MATLAB Examine 16-QAM Using MATLAB 或者,在matlab中,键入&#x…

大模型微调方法:冻结方法 Freeze、P-Tuning 系列、LoRA、QLoRA

大模型微调方法 冻结方法 FreezeP-Tuning 系列Prefix-TuningPrompt TuningP-Tuning v1P-Tuning v2 LoRAQLoRA 冻结方法 Freeze 方法意思是,只用少部分参数训练,把模型的大部分参数冻结。 只要设置微调层的参数: # 遍历模型的所有参数和名称…

汉缆股份携手航天科技AIRIOT建设智慧工厂,加速数字化转型升级

工业4.0时代,工厂早已不是传统概念里流水线与机器制造的简单叠加,而是伴随工业互联网技术的发展,持续朝数字化与智能化方向演进,打造智慧工厂已成为众多制造企业转型升级的共同选择。近期,航天科技控股集团股份有限公司…

拦截器与过滤器的区别

1.最通俗的理解 过滤器:你要从一堆请求中通过一个工具挑选出符合你要求的请求,而这个工具就是过滤器 拦截器:当一个流程正在进行时,你希望干预它的进展,甚至是直接将它终止 2.触发时机不同 过滤器是在请求进入容器…

基于SSM的药房药品采购集中管理系统的设计与实现论文

摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对药房药品采购信息管理混乱,出错率高,信息安全…

shiro入门demo(一)身份验证

shiro&#xff08;身份&#xff09;认证&#xff0c;简单来说就是登录/退出。搭建springboot项目&#xff0c;引入shiro和单元测试依赖&#xff1a; <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-…

python程序编程代码大全,python编程代码详解

这篇文章主要介绍了python语言的代码书写规则有哪些&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 Python代码主要由&#xff1a;5个部分组成&#xff0c;下面就分别介绍&…

数据清洗、特征工程和数据可视化、数据挖掘与建模的主要内容

1.4 数据清洗、特征工程和数据可视化、数据挖掘与建模的内容 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解1.4节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学…

什么是纯净IP?如何判断IP地址的纯净度?有哪些干净IP推荐?

您是否想知道什么使代理“干净”或如何确保您的代理不会将您列入网站的黑名单&#xff1f;对于通过代理访问网络的人来说&#xff0c;干净的代理是无缝在线体验的重要组成部分。在这篇文章中&#xff0c;我们将深入研究干净代理的世界&#xff0c;并探讨决定其质量的因素。 一、…

字节跳动面经题

字节跳动面经题 1、了解anchor-free? "Anchor-free"是一个指向一类目标检测方法的术语&#xff0c;与传统的"anchor-based"方法相对应。在传统的目标检测中&#xff0c;通常会使用一系列预定义的锚框&#xff08;anchors&#xff09;作为模型的基础。这些…