<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>OS on Cylon&#39;s Collection</title>
    <link>https://www.oomkill.com/tags/os/</link>
    <description>Recent content in OS on Cylon&#39;s Collection</description>
    <generator>Hugo -- 0.125.7</generator>
    <language>zh</language>
    <lastBuildDate>Wed, 22 Mar 2023 23:00:36 +0800</lastBuildDate>
    <atom:link href="https://www.oomkill.com/tags/os/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>ch12 进程间通讯</title>
      <link>https://www.oomkill.com/ch12-ipc/</link>
      <pubDate>Tue, 03 May 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch12-ipc/</guid>
      <description>Overview 进程间是相互保持独立的，内存管理中，就是保护进程的地址空间不被其他进程访问。而进程间通信 ( Inter-process Communication IPC) 用于在一个或多个进程间交换数据
进程间合作是那些可以影响或受其他过程影响的过程。例如网站包含 JS、H5、Flash，当有一个相应缓慢时，会发生整个网站的布局或其他功能的展示。
通常情况下进程间合作被允许的原因有：
信息共享：多个进程需要访问同一个文件。（如管道）
计算加速：将复杂功能拆分为多个子任务（多处理器时效果更佳），可以更快地解决问题
模块化：将整体系统架构分为不同功能模块，模块间相互协作
便利：单用户可以同时多任务处理，如 编辑、编译、打印等
Communications model (a) 消息队列（间接通信） &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(b) 共享内存（直接通信） Message Passing IPC背后关键的一点是消息的传递，即一个进程发消息，一个进程接收消息
而为了使进程间通信，就必须在进程间建立连接，连接可以是单/双向。连接可以使用直接通信和间接通信来实现
Direct Communication 直接通信，必须明确声明发送者或接收者的名称，通常定义为：
Send(P, message)：发送信息到进程 P Receive(Q, message)：接收来自进程 Q 的信息 在直接通信中，一般连接的属性有以下特征：
一个链路与一对进程相关联 自动建立链接 链接是通用的双向链接 Indirect Communication 间接通信，为异步通信，通常情况下互通信都需要有消息队列；发送者将信息放置消息队列中，接受者从消息队列中取出消息
Send(P, message)：像消息队列发送消息 Receive(Q, message)：接受消息队列中的消息 每个进程都有唯一ID 共享一个消息队列 在间接通信中，一般连接的属性有以下特征：
一对进程共享消息队列时，才会在进程之间建立链接 链接可以被许多进程关联 链接可以是单向也可以是双向 每个进程可以有多个链接 &amp;nbsp;&amp;nbsp;直接通信&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;间接通信 Synchronization 从另一方面来讲，消息传递可以是阻塞 Blocking 或非阻塞 Non-Blocking 的；同步 synchronous 会阻塞一个进程，直到发送完成。异步 asynchronous 则是是非阻塞的，发送操作完成后会立即返回不等待返回结果
Buffer 消息通过队列传递，队列的容量则具有下列三种配置之一：
0容量：消息不能存储在队列中，因此发送者必须阻塞，直到接收者接受消息 有限容量：队列中有一定的预先约定大小的容量。如果队列已满，发送者必须阻塞，直到队列中有可用空间（反之为空，接受者阻塞），否则可能是阻塞的或非阻塞的 无限容量：具有无限容量的队列，发送者永远不会被迫阻塞 至此整节围绕对消息传递功能的三个方面做了介绍：</description>
    </item>
    <item>
      <title>ch13 file system</title>
      <link>https://www.oomkill.com/ch13-file-system/</link>
      <pubDate>Tue, 03 May 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch13-file-system/</guid>
      <description>Overview 文件系统和文件 文件系统: 一种用于持久性存储的系统抽象，决定了辅存中的内容如何组织与存储的抽象概念
文件：文件系统中的一个单元的相关数据在操作系统中的抽象，展现给用户的抽象概念
文件系统的功能：
分配文件磁盘空间 管理文件块(哪一块属于哪一个文件) 管理空闲空间(哪一块是空闲的) 分配算法(策略) 管理文件集合 定位文件及其内容 命名：通过名字找到文件的接口 最常见：分层文件系统 文件系统类型(组织文件的不同方式) 提供的便利及特征 保护：分层来保护数据安全 可靠性，持久性：保持文件的持久即使发生崩溃,媒体错误,攻击等 为什么需要文件系统：
如果将文件放入一个房间中，整个房间都是堆积的文件
有了文件系统的存在将会改变一切
空间管理、元数据、数据加密、文件访问控制和数据完整性等等都是文件系统的职责。
文件属性 文件具有名称和数据，还存储文件创建日期和时间、当前大小、上次修改日期等元信息。所有这些信息都称为文件系统的属性。常见的文件属性有
名称：它是以人类可理解的形式。 标识符：每个文件都由文件系统中的唯一标记号标识，称为标识符。 位置：设备上的文件位置。 类型：支持各种类型文件的系统需要此属性。 大小：当前文件大小的属性。 保护：分配和控制读、写和执行文件的访问权限。 时间、日期和安全：用于对文件的保护、安全，也用于监控 文件描述符 文件头 File Header；类似于Unix的 inode，在存储元数据中保存了每个文件的信息，保存文件的属性，跟踪哪一块存储块属于逻辑上文件结构的哪个偏移
文件描述符 （file-descriptor）；是唯一标识操作系统中打开文件的数字（整形），用于用户和内核空间之间的接口，以识别 文件/Socket 资源。因此，当使用 open() 或 socket()（与内核接口的系统调用）时，会得到一个文件描述符，一个整数。因此，如果直接与内核交互，使用系统调用 read(), write() 等 close()。使用的是一个文件描述符句柄。
在 C 语言中 stdin，stdout、 和 stderr ，在 UNIX 中分别映射到文件描述符 0 1 2
text 1 2 3 4 5 f = open(name, flag); ... .</description>
    </item>
    <item>
      <title>ch11 死锁</title>
      <link>https://www.oomkill.com/ch11-deadlock/</link>
      <pubDate>Mon, 02 May 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch11-deadlock/</guid>
      <description>死锁问题 死锁 deadlock；是一组阻塞的进程，每个进程都持有一个资源并等待获取另一个进程持有的资源。
死锁的示例：交通桥
如图所示，桥是资源，进程是车辆，两个不同方向的车辆同时占用桥，此时发生谁也过不去的情况（死锁的发生）；
当死锁发生时，如果一辆车倒车（抢占资源和回滚）就可以解决死锁问题 死锁发生时，可能需要后退多台车辆 饥饿，而饥饿并不一定是死锁 系统模型 在正常情况下，进程必须在使用之前请求资源，并在完成后释放它，顺序如下：
请求：如果不能立即授予请求，则进程等待，直到它需要的资源变得可用。例如，系统调用 open()、malloc()、new() 、request() 等。
使用：进程使用资源，例如文件中读取数据；使用硬件。
释放：进程完成后放弃资源，以便其可用于其他进程。如，close()、free()、delete() 、 release()。
当在集合中的每个进程都在等待当前分配给集合中另一个进程的资源时，这一组进程就会发生死锁
资源分配 通过实例来理解死锁，
一组资源：
${ R_1,\ R_2,\ R_3,\ &amp;hellip;.,\ R_N }$；为方形，图形内的点代表资源数量 一组进程：
${ P_1,\ P_2,\ P_3,\ &amp;hellip;.,\ P_N }$ 请求边缘 Request Edge：进程需要一些资源，被称为请求边缘；如 $P_i\ →\ R_j$
分配边缘 Assign Edge：当资源已经被分配给进程，被称为分配边缘；如 $R_j\ →\ P_i$
当请求被授予时，可以通过反转方向的线将请求边缘转换为分配边缘
类型 示意图 Process Resource $P_i$ 请求的 $R_j$ 实例 $P_i$ 持有一个 $R_j$ 的实例
也可以说 $R_j$ 被 $P_i$ 所持有 资源分配图 资源分配图 如图所示，资源类型为：</description>
    </item>
    <item>
      <title>ch10 信号量和监视器</title>
      <link>https://www.oomkill.com/ch10-semaphore-and-monitors/</link>
      <pubDate>Sun, 01 May 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch10-semaphore-and-monitors/</guid>
      <description>Backgound 信号量 semaphores，是操作系统中非常重要的技术，通过使用一个简单的整数值来管理并发进程，信号量只是一个在线程之间共享的整数变量。该变量用于解决临界区问题并实现进程同步。 信号量具有两个原子操作：
P()：sem减一，如果sem&amp;lt;0，等待；否则继续 V()：sem加一，如果sem≤0，唤醒一个等待的P； Semaphore 信号量的使用 型号量的特点：
两个类型信号量
二进制信号量 Binary Semaphore：也称为互斥锁。它只能有两个值0和1。它的值被初始化为1。它用于实现多进程临界区问题的解决。
计数信号量 Counting Semaphore：值可以跨越一个不受限制的域（可以取任何非负数）。它用于控制对具有多个实例的资源的访问。
信号量是被保护的变量
初始化完成后，唯一改变一个信号量的值的办法是通过P() 和 V()
操作必须是原子
P() 能够阻塞，V() 不会阻塞
信号量可以用在2个方面
互斥
条件同步(调度约束 —— 一个线程等待另一个线程的事情发生)
信号量实现的互斥 c 1 2 3 4 5 6 7 mutex = new Semaphore(1); mutex-&amp;gt;P(); // 临界区前p ... critical section ... mutex-&amp;gt;V(); // 临界区后v 信号量实现调度约束 c 1 2 3 4 5 6 7 8 9 10 condition = new Semaphore(0); // Thread A .</description>
    </item>
    <item>
      <title>ch8 CPU调度算法</title>
      <link>https://www.oomkill.com/ch8-cpu-scheduling-algorithms/</link>
      <pubDate>Sat, 30 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch8-cpu-scheduling-algorithms/</guid>
      <description>Overview CPU调度 (cpu scheduling )，是决定在一个时间窗口内，哪个进程可以拥有CPU而另外一个个进程会被暂停的过程。CPU调度的作用是为了确保每当CPU空闲时，操作系统至少选择就绪队列中一个可用的进程执行。这个选择过程将由CPU调度器来执行。
调度程序：挑选就绪进程的内核函数
调度策略：依据什么挑选进程？ 调度时机：什么时间进行调度？ 进程从运行状态切换到等待状态 进程退出 非抢占式：当前进程主从放弃CPU时， 抢占式：当前进程被抢占 时间片用完 进程从等待切换到就绪（当前就绪进程优先级高于当前运行进程） 调度准则 CPU的调度策略 抢占式调度 抢占式调度（Preemptive）在分配进程时有对应的优先级。而在另一个较低优先级进程之前运行具有较高优先级的进程很重要，即使较低优先级的进程仍在运行。较低优先级的进程扔会等待一段时间，让较高优先级的进程完成执行后恢复。
抢占式调度主要发生在运行状态切换到就绪或等待状态
非抢占式调度 非抢占式调度 （Non-Preemptive），在这种类型的调度中，一旦将资源（CPU 周期）分配给一个进程，该进程就会持有CPU使用权，直到它被终止或达到等待状态。
抢占式调度主要发生在运行状态终止的情况下
如何确定调度是抢占式还是非抢占式？ 一般来讲，确定调度的方式是通过以下四点来确定的：
当进程从运行状态切换到等待状态；如I/O请求或调用 wait() 系统调用 当进程从运行状态切换到就绪状态；如响应中断。 当进程从等待状态切换到就绪状态；如在 I/O 完成或从 wait() 返回时。 进程完成执行并终止； 如果调度发生在1 4情况下，则为非抢占式，否则为抢占式
程序执行模型 需要关注的是进程在计算机系统中运行时存在什么状态？
几乎所有进程都在一个连续的循环的两种模型之间交替：即CPU突发和I/O突发中交替
每个调度决定都是关于在下一个CPU突发时将哪个工作交给CPU 在时间分片机制下，线程可能在结束当前CPU突发前被迫放弃CPU CPU突发和 I/O突发的交替序列逻辑CPU 突发型的持续时间调度指标 在了解评价指标前，需要对CPU调度中的一些术语需要了解
CPU突发 （Burst Time BT）：进程开始执行的时间，从到达到开始执行花费的时间 到达时间 （Arrival Time AT）：进程到达就绪队列的时间 完成时间（End Time ET 或 Completion Time CT）：进程执行完成的时间 等待时间 （Waiting Time WT）：进程在就绪队列中等待轮到 CPU 占用的时间；$WT = TT - BT$ 周转时间 （Turnaround Time TT）：完成时间和到达时间的差 $TT=CT-AT$ 相应时间（Response Time RT）：开始响应请求所需的时间。第一次请求到相应的时间。 吞吐量 (Throughput)：单位时间内完成的进程数。$Throughput = (Number\ of\ processes\ completed) \div (Time\ unit)$ 一般情况下，需要的服务”越快“越好，而快的定义：</description>
    </item>
    <item>
      <title>ch9 同步</title>
      <link>https://www.oomkill.com/ch9-synchronization/</link>
      <pubDate>Sat, 30 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch9-synchronization/</guid>
      <description>Background 多进程作为现代操作系统的重要特性，交互则会引起同时对共享资源的访问，当这些资源访问不正确会出现冲突或产生不适当的输出（冲突、死锁、饥饿）；而在同步的基础上，进程被分为以下两种类型：
独立进程 Independent Process 不和其他进程共享资源或状态 确定性，输入状态确定结果 可重现，能够重现起始条件，I/O 调度的顺序不重要 协作进程 Cooperative Process； 多进程共享资源或状态 不确定性 probabilistic 不可重现 不确定性和不可重现意味着bug可能是间歇性发生的
Cooperation 进程的互相影响，即进程间的合作（相互或破坏）；最简单的例子就是两个进程使用同一个文件，一个进程读，一个进程写。读进程的结果会被写进程所影响。
进程需要合作的原因：
资源共享：多个进程访问相同的数据 一台电脑，多个用户 一个银行存款余额,多台ATM机 嵌入式系统（机器人手臂和收的协调） 计算加速： I/O 和 CPU计算可重叠 多处理器 - 将任务分解为子任务并分布在不同的进程中，它通常可以更快地运行（也需要多个可共享的 CPU） 模块化：复杂的任务组织成单独的子任务，让不同的进程运行 大程序分成小程序 是系统易于扩展 程序可以调用函数fork()来创建一个新的进程
操作系统需要分配一个新的并且唯一的进程ID 因此在内核中,这个系统调用会运行 new_pid = next_pid++; 翻译成机器指令: Load next_pid Reg1 STORE Reg1 new_pid INC Reg1 STORE Reg1 next_pid 假设两个进程并发执行
如果next_pid等于100, 那么其中一个进程得到的ID应该是100, 另一个进程的ID应该是101, next_pid应该增加到102 可能在INC前进行了上下文切换, 最终导致两个进程的pid都是100,而next_pid也是101 无论多个线程的指令序列怎样交替执行,程序都必须正常工作
多线程程序具有不确定性和不可重现的特点 不经过专门设计,调试难度很高 不确定性要求并行程序的正确性
先思考清楚问题，把程序的行为设计清楚 切忌给予着手编写代码，碰到问题再调试 Race Condition 竞态条件是由操作系统软件中的同步错误。出现在进程试图同时执行两个或多个操作时，这是一种不希望出现的情况。
怎么样避免竞态?</description>
    </item>
    <item>
      <title>ch7 进程管理</title>
      <link>https://www.oomkill.com/ch7-process-management/</link>
      <pubDate>Fri, 29 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch7-process-management/</guid>
      <description>Overview 进程的描述 进程的状态 State 线程 Thread 进程间通信 Inter-Process Communication 进程互斥与同步 死锁 DeadLock 进程的描述 在操作系统中，通常来说进程 Process 是当前正在执行的东西。因此，一个具有一定独立功能的程序在一个数据集合上的一次动态执行过程，可以称之为进程。
程序是静态的文件
进程是程序动态执行的过程
进程的组成 进程包括 :
程序的代码 程序处理的数据 程序计数器 (PC) 中的值, 指示下一条将运行的指令 一组通用的寄存器的当前值, 堆 Heap , 栈 Stack 一组系统资源(如打开的文件、内存、网络) 而进程的主要构成如下，
Stack Section Heap Section Data Section Text Section Stack Stack部分包含：
局部变量 函数和返回地址 main函数 如上图所示，Stack和 heap 以相反的方向增长，如果两者都以相同的方向增长，那么其两者可能会重叠，因此如果它们以相反的方向增长则很好。
示例：如，调用下列函数时，将存储在Stack部分，一旦函数返回，该函数堆栈部分的值将被删除。
Stack上有一个堆栈帧，其中包含main函数以及局部变量a, b sum 。使用 printf()，创建的帧以及局部变量只能在内存中访问，帧的持续时间在从函数 return 0 后释放。
c 1 2 3 4 5 6 7 8 int main(void) { int a, b, sum; a = 2; b = 3; sum = a + b; printf(&amp;#34;%d\n&amp;#34;, sum); return 0 } Stack是一种后进先出 (LIFO) 数据结构，最后一个被推到Stack上的内容就是从顶部弹出的第一个内容。不允许从Stack的中间插入或移除。因此Stack必须至少支持两种操作：push 和 pop ；其他操作也是可以，但不是必需的。</description>
    </item>
    <item>
      <title>ch6 页面置换算法</title>
      <link>https://www.oomkill.com/ch6-page-replacement-algorithms/</link>
      <pubDate>Thu, 28 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch6-page-replacement-algorithms/</guid>
      <description>Overviews 功能与目标 实验设置与评价方法 局部页面算法 最优页面置换算法 先进先出算法 最近最久未使用算法 时钟页面置换算法 最不常用置换算法 Belady现象 LRU FIFO Clock对比 全局页面置换算法 工作集模型 工作集页面置换算法 缺页率置换算法 功能与目标 功能 : 当缺页中断发生，需要调入新的页面而内存已满时，选择内存当中哪个物理页面被置换。
目标 : 尽可能地减少页面的换进换出次数(即缺页中断的次数)。 具体来说，把未来不再使用的或短期内较少使用的页面换出，通常只能在局部性原理指导下依据过去的统计数据来进行预测。
页面锁定 frame locking：用于描述必须常驻内存的操作系统的关键部分或时间关键（time critical）的应用进程。实现的方式是：在页表中添加锁定标记位(lock bit)。
实验设置与评价方法 实例：记录一个进程对页访问的一个轨迹
举例 : 模拟一个实验环境，记录对应的地址访问序列，虚拟地址跟踪(页号, 偏移)&amp;hellip; (3,0) (1,9) (4,1) (2,1) (5,3) (2,0) &amp;hellip; 而offset可以忽略（页不存在才会产生 page fault），生成的页面轨迹 3, 1, 4, 2, 5, 2, 1, &amp;hellip;（替换为，3,1,4,2,5,2,1） 模拟一个页面置换的行为并且记录产生页缺失数的数量
更少的缺失，更好的性能 局部页面置换算法 最优页面置换算法 基本思路：当一个缺页中断发生时，对于保存在内存当中的每一个逻辑页面，计算在它的下一次访问之前，还需等待多长时间，从中选择等待时间最长的那个，作为被置换的页面。
这是一种理想情况, 在实际系统中是无法实现的, 因为操作系统无法知道每一个页面要等待多长时间以后才会再次被访问.
最优页面置换算法（Optimal Page Replacement）可用作其他算法的性能评价的依据，(在一个模拟器上运行某个程序, 并记录每一次的页面访问情况，在第二遍运行时即可使用最优算法)
在该算法中，会替换在未来最长持续时间内不会使用的页面。如下图所示有 a b c d e五个页，但是只有四个页帧。此时会产生物理页不够，会产生 Page Fault。</description>
    </item>
    <item>
      <title>ch5 虚拟内存</title>
      <link>https://www.oomkill.com/ch5-virtual-memory/</link>
      <pubDate>Wed, 27 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch5-virtual-memory/</guid>
      <description>Objective 覆盖技术 交换技术 虚拟内存 目标 程序局部性原理 基本概念 基本特征 虚拟页式内存管理 覆盖技术 overlay 在固定分区中的主要遇到的问题是进程的大小受到分区的最大大小的限制，这将意味着一个进程将不能跨越另一个进程。为了解决这个问题，早期使用了称为覆盖(overlay) 的解决方案，覆盖技术是为了在较小的可用内存中运行较大的程序。常用于多道程序系统，与分区存储管理配合使用。这样并非所有模块都需要同时存在于内存中，实现了运行大于物理内存大小的程序的技术。
覆盖技术的原理： 将程序按照执行逻辑拆分为多个功能上相对独立的部分（overlays）, 那些不会同时执行的模块共享同一块内存区域, 按时间先后来运行（分时）。 必要部分，常驻内存的代码和数据，负责管理，在某个时间片将相应的程序和数据导入或导出内存。 可选部分，在其他程序模块中实现, 平时存放在外存中, 在需要用到时才装入内存; 不存在调用关系的模块不必同时装入到内存, 从而可以相互覆盖, 即这些模块共用一个分区. 覆盖技术实例 覆盖技术说明：
有一个程序，分位A B C D E F G 六个模块，每一个模块占用了一定空间，程序的覆盖树如图所示。
问：当满足加载（和运行）该程序所需物理内存中的大小是多少？
使用覆盖技术，实际上不需要将整个程序放在主内存中。只需要在对应时间片时所需要的部分即可，其逻辑调用关系树可以分为：Root-A-D或者 Root-A-E ; Root-B-F 或 Root-C-G 部分。
Root是常驻内存，因为其需要调用A B C D E F G 六个模块，占用2KB
如图：加载与运行改程序所需的物理内存大小是多少？
​	(a) 12 KB
​	(b) 14 KB
​	(c) 10 KB
​	(d) 8 KB
答：由公式可得，最大运行层所需的物理内存为14KB，即拥有 14KB 大小的分区就可以运行上图任意一个分区</description>
    </item>
    <item>
      <title>ch4 操作内存管理 - 非连续内存分配</title>
      <link>https://www.oomkill.com/ch4-non-contiguous-memory-allocation/</link>
      <pubDate>Tue, 26 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch4-non-contiguous-memory-allocation/</guid>
      <description>overview Q1: 为什么需要非连续内存分配
连续内存管理 （contiguous memory allocation）, 即 : 操作系统加载到内存以及程序加载到内存中时, 分配一块连续的内存块. 但这种方式会出现碎片问题，而非连续内存分配（Non-contiguous memory allocation ）可以有效的减少碎片（Fragmentation）的出现。
Q2: 主要的非连续内存分配的管理方法
分段（Segmentation） 分页（Paging） 页表 （Page Table） 1.非连续内存分配的必要性 连续内存管理的缺陷：
内存利用率较低（memory wastage），在程序运行时分配的内存是增长的，但在进程使用为达到分配大小时，分配的块并未使用，并且也不能给其他进程使用，造成了内存的浪费。 分配给一个程序的物理内存必须是连续的。 碎片化问题 不灵活（inflexibility），当进程或文件使用的内存超出预期时（即：超出分配的内存块大小），将停止并抛出异常，例如：No disk space。 非连续内存分配的优点:
一个程序的物理地址空间是非连续的 更好的内存利用和管理，（减少了内存浪费） 允许共享代码与数据(共享库等&amp;hellip;) 支持动态加载和动态链接 非连续内存分配的缺点：
建立虚拟地址和物理地址的转换难度大 软件方案 硬件方案(采用硬件方案) : 分段 / 分页 分段（segmentation） 首先 segmentation mechanism需要考虑的问题：
程序的分段地址空间 分段寻址方案 什么是segmentation 段（segmentation）是一个逻辑单元 (logical unit)，例如：
主程序 main program 程序（主要是指功能的代码，如一段函数） procedure 函数 function 方法 method 对象 object 局部变量和全局变量 local variables, global variables 公共块 common block 堆 stack 符号表 symbol table 数组 arrays [segmentation的逻辑视图]可以看到左边是逻辑地址，右边是不连续的物理地址，中间有一个映射机制将两边建立了一个关联关系（ST Segment Table）。通过映射机制将不同的块（如stack，function.</description>
    </item>
    <item>
      <title>ch3 操作内存管理 - 连续内存分配</title>
      <link>https://www.oomkill.com/ch3-contiguous-memory-allocation/</link>
      <pubDate>Mon, 25 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://www.oomkill.com/ch3-contiguous-memory-allocation/</guid>
      <description>一 计算机体系结构及内存分层体系 1.计算机硬件体系结构大致分为
CPU，完成程序的执行控制 主存 （main memory），放置程序代码和数据 I/O（外）设备，配合程序工作。 2.内存分层体系（金字塔结构) 什么是内存结构：CPU所访问的指令和数据在什么地方。
第一类：位于CPU内部，操作操作系统无法直接进行管理的，寄存器，cache；特点，速度快，容量小
第二类：主存或物理内存，主要用来放置操作系统本身及要运行的代码；其特点是，容量比cache要大很多，单速度交于cache要慢一些。
第三类：磁盘，永久保存的数据及代码，当对于主存要慢，容量比主存大很多。
操作系统的作用可以将数据访问的速度（cache与内存）与存储的大小（硬盘）很好的融合在一起
3.OS管理内存时需要完成的目标
① 抽象：逻辑地址空间（将物理内存，外设等抽象成逻辑地址空间，只需要访问对应地址空间)
② 保护（独立）：操作系统完成隔离机制实现，独立地址空间（每段程序执行时，不受其他程序的影响）
③ 共享：进程间安全，可靠，有效，进行数据传递，访问相同的内存。
④ 虚拟化：更多的地址空间（利用磁盘的空间) 4.需要完成在操作系统中管理内存的不同方法
操作系统层面
程序重定位
分段
分页
虚拟内存
按需分页虚拟内存
硬件层面
必须知道内存架构 MMU(内存管理单元)：处理CPU的内存访问请求 二 地址空间&amp;amp;地址生成 地址空间的定义
地址生成器
地址安全检查
1.内存地址的定义 ① 物理内存地址：硬件支持的地址空间，如主存（内存）和硬盘，由硬件完成管理和控制 ② 逻辑内存地址：一个程序运行时所需要的内存范围。
两者间的关系：逻辑地址空间最终是一个存在的物理地址空间，两者间的映射关系是由操作系统来管理的
2.逻辑地址生成过程（把代码转化为计算机能理解语言） 一段代码运行→编译→汇编语言→机器语言→产生链接文件→将硬盘中程序载入到内存当中运行（完成逻辑地址的分配）
如C中变量的名字，函数的位置，为逻辑地址。
3.物理地址生成（逻辑地址对应的物理地址的过程） CPU方面 MMU表示映射关系
① CPU ALU Arithmetic logic unit 发出请求，为逻辑地址 ② CPU MMU Memory management unit 查找逻辑地址映射表，不存在会去内存中找 ③ 控制器提出内存请求（需要的内容，内容即指令） 内存方面
④ 内存通过bus发送物理内存地址的内容给CPU OS方面 建立逻辑地址和物理地址之间的映射关系（需在前四部前将映射管理建立好）</description>
    </item>
  </channel>
</rss>
