【理论·专业课】第三次作业

第1题(存储管理_内存碎片)

请指出内部碎片与外部碎片的区别。


ANS:

内部碎片是分配给进程但未被进程使用且无法被其他进程利用的内存空间

外部碎片是内存中因进程分配释放内存形成的不连续小块,虽总和够但因不连续无法分配给需要连续内存的进程。

第2题(存储管理_内存分配算法)

给定六个内存分区,分别为 100M,170M,40MB,205MB, 300MB 和 185MB (按顺序)。

首次适应、最优适应和最差适应算法将如何放置大小为 200MB、15MB、185MB、75MB、175MB 和 80MB (按顺序) 的进程?

指出哪个请求 (如果有) 不能得到满足。评论每种算法管理内存的效率。


ANS:

1.如何放置

首次适应算法:按地址顺序查找,找到第一个能满足进程大小的空闲分区。

对于 200MB 进程,分配 205MB 分区,剩余 5MB。

15MB 进程分配 40MB 分区,剩余 25MB。

185MB 进程分配 185MB 分区,无剩余。

75MB 进程分配 100MB 分区,剩余 25MB。

175MB 进程分配 300MB 分区,剩余 125MB。

80MB 进程分配 170MB 分区,剩余 90MB。所有进程都能满足。

最优适应算法:从空闲分区列表中选择能满足进程需求且最小的空闲分区。

200MB 进程分配 205MB 分区,剩余 5MB。

15MB 进程分配 40MB 分区,剩余 25MB。

185MB 进程分配 185MB 分区,无剩余。

75MB 进程分配 100MB 分区,剩余 25MB。

175MB 进程分配 175MB 分区,无剩余(从 170MB 和 185MB 中选择更合适的 175MB 分区)。

80MB 进程分配 85MB 分区,剩余 5MB。所有进程都能满足。

最差适应算法:从空闲分区列表中选择最大的空闲分区来满足进程需求。

200MB 进程分配 300MB 分区,剩余 100MB。

15MB 进程分配 185MB 分区,剩余 170MB(选择最大的空闲分区 185MB)。

185MB 进程分配 170MB 分区,无法满足(因为之前 15MB 进程分配了 185MB 分区后剩余的 170MB 不够 185MB)。

75MB 进程分配 100MB 分区,剩余 25MB。

175MB 进程分配 205MB 分区,剩余 30MB。

80MB 进程分配剩余的 100MB 分区,剩余 20MB。

2.是否满足

首次适应算法:进程都能满足,分配后剩余分区分别为 5MB、25MB、0、25MB、125MB、90MB。

最优适应算法:进程都能满足,分配后剩余分区分别为 5MB、25MB、0、25MB、0、5MB。

最差适应算法:185MB 进程不能满足,分配后剩余分区分别为 100MB、170MB、0、25MB、30MB、20MB。

3.效率评论

首次适应算法简单,容易产生外部碎片;最优适应算法能较好利用内存空间,但分配和回收操作较复杂,可能产生较多外部碎片;最差适应算法会使大的空闲分区快速被分割变小,可能导致后续大进程无法分配,也容易产生外部碎片。

第三题(存储管理_分页)

假设页大小为 1KB, 以下地址引用 (以十进制数形式提供) 的页码和偏移量是多少?

a. 21205

b. 164250

c. 121357

d. 16479315

e. 27253187


ANS:

在分页存储管理中,页大小为 1KB = 2^10B,所以地址的二进制的低 10 位为偏移量,其余高位为页码。

对于 21205,21205 / 1024 = 20(页码),21205 % 1024 = 725(偏移量)。

对于 164250,164250 / 1024 = 160(页码),164250 % 1024 = 610(偏移量)。

对于 121357,121357 / 1024 = 118(页码),121357 % 1024 = 505(偏移量)。

对于 16479315,16479315 / 1024 = 16092(页码),16479315 % 1024 = 773(偏移量)。

对于 27253187,27253187 / 1024 = 26614(页码),27253187 % 1024 = 591(偏移量)。

第四题(存储管理_分页)

假设有一个系统具有 32 位的虚拟地址和 4KB 的页面。

编写一个程序,其命令行的输入参数为虚拟地址 (十进制), 其输出为对应的页码和偏移。

例如,你的程序可按如下的代码运行:

复制代码
./addresses 19986

其输出为:

复制代码
The address 19986 contains:
page number = 4
offset = 3602

ANS:

因为页大小为 ,所以偏移量占 位,页码占 位。

通过将输入的虚拟地址右移 12 位得到页码;

用虚拟地址与 0x00000FFF(12 位全 1,用于获取低 12 位)进行按位与操作得到偏移量。

以下是使用Python实现的程序:

python 复制代码
import sys

def address_conversion(virtual_address):
    page_size = 4096  # 4KB
    page_number = virtual_address >> 12
    offset = virtual_address & 0x00000FFF
    print(f"The address {virtual_address} contains:")
    print(f"page number = {page_number}")
    print(f"offset = {offset}")

if __name__ == "__main__":
    if len(sys.argv)!= 2:  #sys.argv 用于获取命令行参数。
        print("Usage: python program.py <virtual_address>")
        sys.exit(1)
    virtual_address = int(sys.argv[1])   
    #sys.argv[0] 是程序本身的名称(在你的例子中是 main.py)
    #而 sys.argv[1] 就是期望用户传入的虚拟地址参数。
    address_conversion(virtual_address)

第五题(存储管理_内存共享与保护)

什么是写时复制功能?在什么情况下它的使用时有效的?实现这种功能需要什么硬件支持?


ANS:

1.定义

写时复制是一种优化技术,当多个进程共享同一块内存页面时,它们最初都以只读方式访问该页面。如果某个进程试图对该页面进行写操作,操作系统会为该进程复制一份该页面的副本,然后让该进程在副本上进行写操作,而其他进程仍然共享原始的只读页面。

2.什么情况有效

在多进程共享大量相同数据且只有少数进程会修改数据的情况下使用有效,这样可以避免为每个进程都复制一份数据,节省内存空间。

3.硬件支持

实现这种功能需要硬件支持内存管理单元(MMU)来跟踪页面的访问权限和执行复制操作。

第六题(虚拟存储管理_请求调页)

假设有一个请求调页存储器。页表保存在寄存器中。

如果有可用空帧或者置换的页面未被修改,则缺页错误的处理需要 8ms, 如果置换的页面已被修改,则需要 20ms。

内存访问时间为 100ns。

假设需要置换的页面在 70% 的时间内会被修改。

对于有效访问时间不超过 200ns, 最大可接受的缺页错误率是多少?


ANS:

设缺页错误率为 。

有效访问时间 = (1 - p) * 内存访问时间 + p *(缺页处理时间 + 内存访问时间)。

当置换页面被修改时,缺页处理时间为 20ms;未被修改时为 8ms,平均缺页处理时间 = 0.7 * 20ms + 0.3 * 8ms = 16.4ms。

代入公式可得:200ns = (1 - p) * 100ns + p * (16.4ms + 100ns),然后解方程,


(约为 0.00061%)

所以最大可接受的缺页错误率约为 0.00061%。

第七题(虚拟存储管理_页面置换算法)

编写一个程序,实现本章节所描述的 FIFO、LRU 和最优页面置换算法。

首先,生成一个随机的页面引用串,其中页码范围为 0~9。将这个随机页面引用串应用到每个算法中,并记录每个算法引起的缺页错误的数量。在启动时将页帧数传递给程序。可以使用所选择的任何编程语言来实现此程序。

ANS:

FIFO 算法:先进先出算法,用队列模拟。新页面入队尾,缺页且队列满时,淘汰队首页面。

LRU 算法:最近最少使用算法,可用字典记录页面访问顺序。页面访问时更新字典,缺页时淘汰最久未使用页面(字典中最早的键)。

最优页面置换算法:置换未来最长时间不被访问的页面。需预先知道页面引用串全部信息,实际难实现,但可用于性能比较。分析引用串,选未来最长时间不被用的页面置换。

python 复制代码
import random

def generate_page_reference_string(length):
    return [random.randint(0, 9) for _ in range(length)]

def fifo(page_reference_string, frame_count):
    frames = []
    page_faults = 0
    for page in page_reference_string:
        if page not in frames:
            if len(frames) == frame_count:
                frames.pop(0)
            frames.append(page)
            page_faults += 1
    return page_faults

def lru(page_reference_string, frame_count):
    frames = {}
    page_faults = 0
    for i, page in enumerate(page_reference_string):
        if page not in frames:
            if len(frames) == frame_count:
                oldest_page = min(frames, key=frames.get)
                del frames[oldest_page]
            frames[page] = i
            page_faults += 1
        else:
            frames[page] = i
    return page_faults

def optimal(page_reference_string, frame_count):
    frames = []
    page_faults = 0
    for i, page in enumerate(page_reference_string):
        if page not in frames:
            if len(frames) == frame_count:
                future_pages = page_reference_string[i + 1:]
                farthest_page = max(frames, key=lambda p: future_pages.index(p) if p in future_pages else float('inf'))
                frames.remove(farthest_page)
            frames.append(page)
            page_faults += 1
    return page_faults

if __name__ == "__main__":
    page_reference_string = generate_page_reference_string(20)
    print("Page reference string:", page_reference_string)
    frame_count = 3
    print("FIFO page faults:", fifo(page_reference_string.copy(), frame_count))
    print("LRU page faults:", lru(page_reference_string.copy(), frame_count))
    print("Optimal page faults:", optimal(page_reference_string.copy(), frame_count))

相关推荐
Apipi*5 小时前
30天速通Linux 第六章信号及信号处理
linux·运维·信号处理
天启HTTP6 小时前
爬虫防封核心原理:IP轮换机制与风控规避逻辑
linux·服务器·网络·爬虫·tcp/ip
代码什么用6 小时前
Spring基础使用
java·后端·spring
运维行者_6 小时前
网络性能监控怎么做?从自动发现到根因分析的4个环节
运维·服务器·网络·人工智能·支持向量机
Su米苏6 小时前
Spring AI 中MCP 与普通 @Tool的区别
java·人工智能·spring
码云数智-园园6 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
老板一杯拿铁6 小时前
Java 异常体系详解:从字节码原理到最佳实践
java
蜗牛互联网7 小时前
Java 17 HttpClient调用文件转写API的超时与失败回退
java·人工智能·后端
禾小西7 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨7 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言